This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #41587] [PATCH] 5.8.8 make sure we get the proper ldflags on libperl.so
[perl5.git] / lib / bigrat.pm
1 package bigrat;
2 use 5.006002;
3
4 $VERSION = '0.09';
5 require Exporter;
6 @ISA            = qw( Exporter );
7 @EXPORT_OK      = qw( ); 
8 @EXPORT         = qw( inf NaN ); 
9
10 use strict;
11 use overload;
12
13 ############################################################################## 
14
15 # These are all alike, and thus faked by AUTOLOAD
16
17 my @faked = qw/round_mode accuracy precision div_scale/;
18 use vars qw/$VERSION $AUTOLOAD $_lite/;         # _lite for testsuite
19
20 sub AUTOLOAD
21   {
22   my $name = $AUTOLOAD;
23
24   $name =~ s/.*:://;    # split package
25   no strict 'refs';
26   foreach my $n (@faked)
27     {
28     if ($n eq $name)
29       {
30       *{"bigrat::$name"} = sub 
31         {
32         my $self = shift;
33         no strict 'refs';
34         if (defined $_[0])
35           {
36           Math::BigInt->$name($_[0]);
37           Math::BigFloat->$name($_[0]);
38           return Math::BigRat->$name($_[0]);
39           }
40         return Math::BigInt->$name();
41         };
42       return &$name;
43       }
44     }
45  
46   # delayed load of Carp and avoid recursion
47   require Carp;
48   Carp::croak ("Can't call bigrat\-\>$name, not a valid method");
49   }
50
51 sub upgrade
52   {
53   my $self = shift;
54   no strict 'refs';
55 #  if (defined $_[0])
56 #    {
57 #    $Math::BigInt::upgrade = $_[0];
58 #    $Math::BigFloat::upgrade = $_[0];
59 #    }
60   $Math::BigInt::upgrade;
61   }
62
63 sub _binary_constant
64   {
65   # this takes a binary/hexadecimal/octal constant string and returns it
66   # as string suitable for new. Basically it converts octal to decimal, and
67   # passes every thing else unmodified back.
68   my $string = shift;
69
70   return Math::BigInt->new($string) if $string =~ /^0[bx]/;
71
72   # so it must be an octal constant
73   Math::BigInt->from_oct($string);
74   }
75
76 sub import 
77   {
78   my $self = shift;
79
80   # see also bignum->import() for additional comments
81
82   # some defaults
83   my $lib = ''; my $upgrade = 'Math::BigFloat';
84
85   my @import = ( ':constant' );                         # drive it w/ constant
86   my @a = @_; my $l = scalar @_; my $j = 0;
87   my ($a,$p);
88   my ($ver,$trace);                                     # version? trace?
89   for ( my $i = 0; $i < $l ; $i++,$j++ )
90     {
91     if ($_[$i] eq 'upgrade')
92       {
93       # this causes upgrading
94       $upgrade = $_[$i+1];              # or undef to disable
95       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
96       splice @a, $j, $s; $j -= $s;
97       }
98     elsif ($_[$i] =~ /^(l|lib)$/)
99       {
100       # this causes a different low lib to take care...
101       $lib = $_[$i+1] || '';
102       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
103       splice @a, $j, $s; $j -= $s; $i++;
104       }
105     elsif ($_[$i] =~ /^(a|accuracy)$/)
106       {
107       $a = $_[$i+1];
108       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
109       splice @a, $j, $s; $j -= $s; $i++;
110       }
111     elsif ($_[$i] =~ /^(p|precision)$/)
112       {
113       $p = $_[$i+1];
114       my $s = 2; $s = 1 if @a-$j < 2;   # avoid "can not modify non-existant..."
115       splice @a, $j, $s; $j -= $s; $i++;
116       }
117     elsif ($_[$i] =~ /^(v|version)$/)
118       {
119       $ver = 1;
120       splice @a, $j, 1; $j --;
121       }
122     elsif ($_[$i] =~ /^(t|trace)$/)
123       {
124       $trace = 1;
125       splice @a, $j, 1; $j --;
126       }
127     else
128       {
129       die ("unknown option $_[$i]");
130       }
131     }
132   my $class;
133   $_lite = 0;                                   # using M::BI::L ?
134   if ($trace)
135     {
136     require Math::BigInt::Trace; $class = 'Math::BigInt::Trace';
137     $upgrade = 'Math::BigFloat::Trace';
138     }
139   else
140     {
141     # see if we can find Math::BigInt::Lite
142     if (!defined $a && !defined $p)             # rounding won't work to well
143       {
144       eval 'require Math::BigInt::Lite;';
145       if ($@ eq '')
146         {
147         @import = ( );                          # :constant in Lite, not MBI
148         Math::BigInt::Lite->import( ':constant' );
149         $_lite= 1;                              # signal okay
150         }
151       }
152     require Math::BigInt if $_lite == 0;        # not already loaded?
153     $class = 'Math::BigInt';                    # regardless of MBIL or not
154     }
155   push @import, 'lib' => $lib if $lib ne '';
156   # Math::BigInt::Trace or plain Math::BigInt
157   $class->import(@import, upgrade => $upgrade);
158
159   require Math::BigFloat;
160   Math::BigFloat->import( upgrade => 'Math::BigRat', ':constant' );
161   require Math::BigRat;
162
163   bigrat->accuracy($a) if defined $a;
164   bigrat->precision($p) if defined $p;
165   if ($ver)
166     {
167     print "bigrat\t\t\t v$VERSION\n";
168     print "Math::BigInt::Lite\t v$Math::BigInt::Lite::VERSION\n" if $_lite;  
169     print "Math::BigInt\t\t v$Math::BigInt::VERSION";
170     my $config = Math::BigInt->config();
171     print " lib => $config->{lib} v$config->{lib_version}\n";
172     print "Math::BigFloat\t\t v$Math::BigFloat::VERSION\n";
173     print "Math::BigRat\t\t v$Math::BigRat::VERSION\n";
174     exit;
175     }
176
177   # Take care of octal/hexadecimal constants
178   overload::constant binary => sub { _binary_constant(shift) };
179
180   $self->export_to_level(1,$self,@a);           # export inf and NaN
181   }
182
183 sub inf () { Math::BigInt->binf(); }
184 sub NaN () { Math::BigInt->bnan(); }
185
186 1;
187
188 __END__
189
190 =head1 NAME
191
192 bigrat - Transparent BigNumber/BigRational support for Perl
193
194 =head1 SYNOPSIS
195
196   use bigrat;
197
198   $x = 2 + 4.5,"\n";                    # BigFloat 6.5
199   print 1/3 + 1/4,"\n";                 # produces 7/12
200
201 =head1 DESCRIPTION
202
203 All operators (including basic math operations) are overloaded. Integer and
204 floating-point constants are created as proper BigInts or BigFloats,
205 respectively.
206
207 Other than L<bignum>, this module upgrades to Math::BigRat, meaning that
208 instead of 2.5 you will get 2+1/2 as output.
209
210 =head2 Modules Used
211
212 C<bigrat> is just a thin wrapper around various modules of the Math::BigInt
213 family. Think of it as the head of the family, who runs the shop, and orders
214 the others to do the work.
215
216 The following modules are currently used by bignum:
217
218         Math::BigInt::Lite      (for speed, and only if it is loadable)
219         Math::BigInt
220         Math::BigFloat
221         Math::BigRat
222
223 =head2 Math Library
224
225 Math with the numbers is done (by default) by a module called
226 Math::BigInt::Calc. This is equivalent to saying:
227
228         use bigrat lib => 'Calc';
229
230 You can change this by using:
231
232         use bigrat lib => 'BitVect';
233
234 The following would first try to find Math::BigInt::Foo, then
235 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
236
237         use bigrat lib => 'Foo,Math::BigInt::Bar';
238
239 Please see respective module documentation for further details.
240
241 =head2 Sign
242
243 The sign is either '+', '-', 'NaN', '+inf' or '-inf'.
244
245 A sign of 'NaN' is used to represent the result when input arguments are not
246 numbers or as a result of 0/0. '+inf' and '-inf' represent plus respectively
247 minus infinity. You will get '+inf' when dividing a positive number by 0, and
248 '-inf' when dividing any negative number by 0.
249
250 =head2 Methods
251
252 Since all numbers are not objects, you can use all functions that are part of
253 the BigInt or BigFloat API. It is wise to use only the bxxx() notation, and not
254 the fxxx() notation, though. This makes you independed on the fact that the
255 underlying object might morph into a different class than BigFloat.
256
257 =over 2
258
259 =item inf()
260
261 A shortcut to return Math::BigInt->binf(). Useful because Perl does not always
262 handle bareword C<inf> properly.
263
264 =item NaN()
265
266 A shortcut to return Math::BigInt->bnan(). Useful because Perl does not always
267 handle bareword C<NaN> properly.
268
269 =item upgrade()
270
271 Return the class that numbers are upgraded to, is in fact returning
272 C<$Math::BigInt::upgrade>.
273
274 =back
275
276 =head2 MATH LIBRARY
277
278 Math with the numbers is done (by default) by a module called
279
280 =head2 Cavaet
281
282 But a warning is in order. When using the following to make a copy of a number,
283 only a shallow copy will be made.
284
285         $x = 9; $y = $x;
286         $x = $y = 7;
287
288 If you want to make a real copy, use the following:
289
290         $y = $x->copy();
291
292 Using the copy or the original with overloaded math is okay, e.g. the
293 following work:
294
295         $x = 9; $y = $x;
296         print $x + 1, " ", $y,"\n";     # prints 10 9
297
298 but calling any method that modifies the number directly will result in
299 B<both> the original and the copy being destroyed:
300
301         $x = 9; $y = $x;
302         print $x->badd(1), " ", $y,"\n";        # prints 10 10
303
304         $x = 9; $y = $x;
305         print $x->binc(1), " ", $y,"\n";        # prints 10 10
306
307         $x = 9; $y = $x;
308         print $x->bmul(2), " ", $y,"\n";        # prints 18 18
309
310 Using methods that do not modify, but testthe contents works:
311
312         $x = 9; $y = $x;
313         $z = 9 if $x->is_zero();                # works fine
314
315 See the documentation about the copy constructor and C<=> in overload, as
316 well as the documentation in BigInt for further details.
317
318 =head2 Options
319
320 bignum recognizes some options that can be passed while loading it via use.
321 The options can (currently) be either a single letter form, or the long form.
322 The following options exist:
323
324 =over 2
325
326 =item a or accuracy
327
328 This sets the accuracy for all math operations. The argument must be greater
329 than or equal to zero. See Math::BigInt's bround() function for details.
330
331         perl -Mbigrat=a,50 -le 'print sqrt(20)'
332
333 Note that setting precision and accurary at the same time is not possible.
334
335 =item p or precision
336
337 This sets the precision for all math operations. The argument can be any
338 integer. Negative values mean a fixed number of digits after the dot, while
339 a positive value rounds to this digit left from the dot. 0 or 1 mean round to
340 integer. See Math::BigInt's bfround() function for details.
341
342         perl -Mbigrat=p,-50 -le 'print sqrt(20)'
343
344 Note that setting precision and accurary at the same time is not possible.
345
346 =item t or trace
347
348 This enables a trace mode and is primarily for debugging bignum or
349 Math::BigInt/Math::BigFloat.
350
351 =item l or lib
352
353 Load a different math lib, see L<MATH LIBRARY>.
354
355         perl -Mbigrat=l,GMP -e 'print 2 ** 512'
356
357 Currently there is no way to specify more than one library on the command
358 line. This means the following does not work:
359
360         perl -Mbignum=l,GMP,Pari -e 'print 2 ** 512'
361
362 This will be hopefully fixed soon ;)
363
364 =item v or version
365
366 This prints out the name and version of all modules used and then exits.
367
368         perl -Mbigrat=v
369
370 =back
371
372 =head1 EXAMPLES
373  
374         perl -Mbigrat -le 'print sqrt(33)'
375         perl -Mbigrat -le 'print 2*255'
376         perl -Mbigrat -le 'print 4.5+2*255'
377         perl -Mbigrat -le 'print 3/7 + 5/7 + 8/3'       
378         perl -Mbigrat -le 'print 12->is_odd()';
379         perl -Mbignum=l,GMP -le 'print 7 ** 7777'
380
381 =head1 LICENSE
382
383 This program is free software; you may redistribute it and/or modify it under
384 the same terms as Perl itself.
385
386 =head1 SEE ALSO
387
388 Especially L<bignum>.
389
390 L<Math::BigFloat>, L<Math::BigInt>, L<Math::BigRat> and L<Math::Big> as well
391 as L<Math::BigInt::BitVect>, L<Math::BigInt::Pari> and  L<Math::BigInt::GMP>.
392
393 =head1 AUTHORS
394
395 (C) by Tels L<http://bloodgate.com/> in early 2002 - 2007.
396
397 =cut