This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Urk. Joe's patches were for the maint branch,
[perl5.git] / lib / bigrat.pm
CommitLineData
126f3c5f
JH
1package bigrat;
2require 5.005;
3
b4bc5691 4$VERSION = '0.05';
126f3c5f 5use Exporter;
b4bc5691
T
6@ISA = qw( Exporter );
7@EXPORT_OK = qw( );
8@EXPORT = qw( inf NaN );
126f3c5f
JH
9
10use strict;
11
12##############################################################################
13
14# These are all alike, and thus faked by AUTOLOAD
15
16my @faked = qw/round_mode accuracy precision div_scale/;
17use vars qw/$VERSION $AUTOLOAD $_lite/; # _lite for testsuite
18
19sub AUTOLOAD
20 {
21 my $name = $AUTOLOAD;
22
23 $name =~ s/.*:://; # split package
24 no strict 'refs';
25 foreach my $n (@faked)
26 {
27 if ($n eq $name)
28 {
29 *{"bigrat::$name"} = sub
30 {
31 my $self = shift;
32 no strict 'refs';
33 if (defined $_[0])
34 {
35 Math::BigInt->$name($_[0]);
36 Math::BigFloat->$name($_[0]);
37 }
38 return Math::BigInt->$name();
39 };
40 return &$name;
41 }
42 }
43
44 # delayed load of Carp and avoid recursion
45 require Carp;
46 Carp::croak ("Can't call bigrat\-\>$name, not a valid method");
47 }
48
49sub upgrade
50 {
51 my $self = shift;
52 no strict 'refs';
53# if (defined $_[0])
54# {
55# $Math::BigInt::upgrade = $_[0];
56# $Math::BigFloat::upgrade = $_[0];
57# }
58 return $Math::BigInt::upgrade;
59 }
60
61sub import
62 {
63 my $self = shift;
64
65 # see also bignum->import() for additional comments
66
67 # some defaults
68 my $lib = 'Calc'; my $upgrade = 'Math::BigFloat';
69
70 my @import = ( ':constant' ); # drive it w/ constant
71 my @a = @_; my $l = scalar @_; my $j = 0;
72 my ($a,$p);
73 my ($ver,$trace); # version? trace?
74 for ( my $i = 0; $i < $l ; $i++,$j++ )
75 {
76 if ($_[$i] eq 'upgrade')
77 {
78 # this causes upgrading
79 $upgrade = $_[$i+1]; # or undef to disable
80 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
81 splice @a, $j, $s; $j -= $s;
82 }
83 elsif ($_[$i] =~ /^(l|lib)$/)
84 {
85 # this causes a different low lib to take care...
86 $lib = $_[$i+1] || '';
87 my $s = 2; $s = 1 if @a-$j < 2; # avoid "can not modify non-existant..."
88 splice @a, $j, $s; $j -= $s;
89 }
90 elsif ($_[$i] =~ /^(v|version)$/)
91 {
92 $ver = 1;
93 splice @a, $j, 1; $j --;
94 }
95 elsif ($_[$i] =~ /^(t|trace)$/)
96 {
97 $trace = 1;
98 splice @a, $j, 1; $j --;
99 }
100 else
101 {
102 die ("unknown option $_[$i]");
103 }
104 }
105 my $class;
106 $_lite = 0; # using M::BI::L ?
107 if ($trace)
108 {
109 require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
110 $upgrade = 'Math::BigFloat::Trace';
126f3c5f
JH
111 }
112 else
113 {
114 # see if we can find Math::BigInt::Lite
115 if (!defined $a && !defined $p) # rounding won't work to well
116 {
117 eval 'require Math::BigInt::Lite;';
118 if ($@ eq '')
119 {
120 @import = ( ); # :constant in Lite, not MBI
121 Math::BigInt::Lite->import( ':constant' );
122 $_lite= 1; # signal okay
123 }
124 }
125 require Math::BigInt if $_lite == 0; # not already loaded?
126 $class = 'Math::BigInt'; # regardless of MBIL or not
127 }
128 # Math::BigInt::Trace or plain Math::BigInt
129 $class->import(@import, upgrade => $upgrade, lib => $lib);
130
131 require Math::BigFloat;
132 Math::BigFloat->import( upgrade => 'Math::BigRat', ':constant' );
133 require Math::BigRat;
134 if ($ver)
135 {
136 print "bigrat\t\t\t v$VERSION\n";
137 print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;
138 print "Math::BigInt\t\t v$Math::BigInt::VERSION";
139 my $config = Math::BigInt->config();
140 print " lib => $config->{lib} v$config->{lib_version}\n";
141 print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
142 print "Math::BigRat\t\t v$Math::BigRat::VERSION\n";
143 exit;
144 }
b4bc5691 145 $self->export_to_level(1,$self,@a); # export inf and NaN
126f3c5f
JH
146 }
147
b4bc5691
T
148sub inf () { Math::BigInt->binf(); }
149sub NaN () { Math::BigInt->bnan(); }
150
126f3c5f
JH
1511;
152
153__END__
154
155=head1 NAME
156
b4bc5691 157bigrat - Transparent BigNumber/BigRationale support for Perl
126f3c5f
JH
158
159=head1 SYNOPSIS
160
161 use bigrat;
162
163 $x = 2 + 4.5,"\n"; # BigFloat 6.5
164 print 1/3 + 1/4,"\n"; # produces 7/12
165
166=head1 DESCRIPTION
167
168All operators (inlcuding basic math operations) are overloaded. Integer and
169floating-point constants are created as proper BigInts or BigFloats,
170respectively.
171
172Other than L<bignum>, this module upgrades to Math::BigRat, meaning that
173instead of 2.5 you will get 2+1/2 as output.
174
175=head2 MODULES USED
176
177C<bigrat> is just a thin wrapper around various modules of the Math::BigInt
178family. Think of it as the head of the family, who runs the shop, and orders
179the others to do the work.
180
181The following modules are currently used by bignum:
182
183 Math::BigInt::Lite (for speed, and only if it is loadable)
184 Math::BigInt
185 Math::BigFloat
186 Math::BigRat
187
188=head2 MATH LIBRARY
189
190Math with the numbers is done (by default) by a module called
191Math::BigInt::Calc. This is equivalent to saying:
192
193 use bigrat lib => 'Calc';
194
195You can change this by using:
196
197 use bigrat lib => 'BitVect';
198
199The following would first try to find Math::BigInt::Foo, then
200Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
201
202 use bigrat lib => 'Foo,Math::BigInt::Bar';
203
204Please see respective module documentation for further details.
205
206=head2 SIGN
207
208The sign is either '+', '-', 'NaN', '+inf' or '-inf' and stored seperately.
209
210A sign of 'NaN' is used to represent the result when input arguments are not
211numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
212minus infinity. You will get '+inf' when dividing a positive number by 0, and
213'-inf' when dividing any negative number by 0.
214
215=head2 METHODS
216
217Since all numbers are not objects, you can use all functions that are part of
218the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
219the fxxx() notation, though. This makes you independed on the fact that the
220underlying object might morph into a different class than BigFloat.
221
222=head1 EXAMPLES
223
224 perl -Mbigrat -le 'print sqrt(33)'
225 perl -Mbigrat -le 'print 2*255'
226 perl -Mbigrat -le 'print 4.5+2*255'
227 perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'
228 perl -Mbigrat -le 'print 12->is_odd()';
229
230=head1 LICENSE
231
232This program is free software; you may redistribute it and/or modify it under
233the same terms as Perl itself.
234
235=head1 SEE ALSO
236
237Especially L<bignum>.
238
239L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
240as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
241
242=head1 AUTHORS
243
244(C) by Tels L<http://bloodgate.com/> in early 2002.
245
246=cut