3 # "Tax the rat farms." - Lord Vetinari
6 # The following hash values are used:
7 # sign : +,-,NaN,+inf,-inf
9 # _n : numeraotr (value = _n/_d)
12 # You should not look at the innards of a BigRat - use the methods for this.
20 use vars qw($VERSION @ISA $upgrade $downgrade
21 $accuracy $precision $round_mode $div_scale $_trap_nan $_trap_inf);
23 @ISA = qw(Math::BigFloat);
27 use overload; # inherit overload from Math::BigFloat
31 *objectify = \&Math::BigInt::objectify; # inherit this from BigInt
32 *AUTOLOAD = \&Math::BigFloat::AUTOLOAD; # can't inherit AUTOLOAD
33 # we inherit these from BigFloat because currently it is not possible
34 # that MBF has a different $MBI variable than we, because MBF also uses
35 # Math::BigInt::config->('lib'); (there is always only one library loaded)
36 *_e_add = \&Math::BigFloat::_e_add;
37 *_e_sub = \&Math::BigFloat::_e_sub;
38 *as_int = \&as_number;
39 *is_pos = \&is_positive;
40 *is_neg = \&is_negative;
43 ##############################################################################
44 # Global constants and flags. Access these only via the accessor methods!
46 $accuracy = $precision = undef;
52 # These are internally, and not to be used from the outside at all!
54 $_trap_nan = 0; # are NaNs ok? set w/ config()
55 $_trap_inf = 0; # are infs ok? set w/ config()
57 # the package we are using for our private parts, defaults to:
58 # Math::BigInt->config()->{lib}
59 my $MBI = 'Math::BigInt::Calc';
62 my $class = 'Math::BigRat';
66 return 0 if $_[1] =~ /^Math::Big(Int|Float)/; # we aren't
70 ##############################################################################
74 # turn a single float input into a rational number (like '0.1')
77 return $self->bnan() if $f->is_nan();
78 return $self->binf($f->{sign}) if $f->{sign} =~ /^[+-]inf$/;
80 $self->{_n} = $MBI->_copy( $f->{_m} ); # mantissa
81 $self->{_d} = $MBI->_one();
82 $self->{sign} = $f->{sign} || '+';
85 # something like Math::BigRat->new('0.1');
87 $MBI->_lsft ( $self->{_d}, $f->{_e} ,10);
91 # something like Math::BigRat->new('10');
93 $MBI->_lsft ( $self->{_n}, $f->{_e} ,10) unless
94 $MBI->_is_zero($f->{_e});
101 # create a Math::BigRat
106 my $self = { }; bless $self,$class;
108 # input like (BigInt) or (BigFloat):
109 if ((!defined $d) && (ref $n) && (!$n->isa('Math::BigRat')))
111 if ($n->isa('Math::BigFloat'))
113 $self->_new_from_float($n);
115 if ($n->isa('Math::BigInt'))
117 # TODO: trap NaN, inf
118 $self->{_n} = $MBI->_copy($n->{value}); # "mantissa" = N
119 $self->{_d} = $MBI->_one(); # d => 1
120 $self->{sign} = $n->{sign};
122 if ($n->isa('Math::BigInt::Lite'))
124 # TODO: trap NaN, inf
125 $self->{sign} = '+'; $self->{sign} = '-' if $$n < 0;
126 $self->{_n} = $MBI->_new(abs($$n)); # "mantissa" = N
127 $self->{_d} = $MBI->_one(); # d => 1
129 return $self->bnorm(); # normalize (120/1 => 12/10)
132 # input like (BigInt,BigInt) or (BigLite,BigLite):
133 if (ref($d) && ref($n))
135 # do N first (for $self->{sign}):
136 if ($n->isa('Math::BigInt'))
138 # TODO: trap NaN, inf
139 $self->{_n} = $MBI->_copy($n->{value}); # "mantissa" = N
140 $self->{sign} = $n->{sign};
142 elsif ($n->isa('Math::BigInt::Lite'))
144 # TODO: trap NaN, inf
145 $self->{sign} = '+'; $self->{sign} = '-' if $$n < 0;
146 $self->{_n} = $MBI->_new(abs($$n)); # "mantissa" = $n
151 Carp::croak(ref($n) . " is not a recognized object format for Math::BigRat->new");
154 if ($d->isa('Math::BigInt'))
156 # TODO: trap NaN, inf
157 $self->{_d} = $MBI->_copy($d->{value}); # "mantissa" = D
158 # +/+ or -/- => +, +/- or -/+ => -
159 $self->{sign} = $d->{sign} ne $self->{sign} ? '-' : '+';
161 elsif ($d->isa('Math::BigInt::Lite'))
163 # TODO: trap NaN, inf
164 $self->{_d} = $MBI->_new(abs($$d)); # "mantissa" = D
165 my $ds = '+'; $ds = '-' if $$d < 0;
166 # +/+ or -/- => +, +/- or -/+ => -
167 $self->{sign} = $ds ne $self->{sign} ? '-' : '+';
172 Carp::croak(ref($d) . " is not a recognized object format for Math::BigRat->new");
174 return $self->bnorm(); # normalize (120/1 => 12/10)
176 return $n->copy() if ref $n; # already a BigRat
180 $self->{_n} = $MBI->_zero(); # undef => 0
181 $self->{_d} = $MBI->_one();
186 # string input with / delimiter
187 if ($n =~ /\s*\/\s*/)
189 return $class->bnan() if $n =~ /\/.*\//; # 1/2/3 isn't valid
190 return $class->bnan() if $n =~ /\/\s*$/; # 1/ isn't valid
191 ($n,$d) = split (/\//,$n);
192 # try as BigFloats first
193 if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/))
195 local $Math::BigFloat::accuracy = undef;
196 local $Math::BigFloat::precision = undef;
198 # one of them looks like a float
199 my $nf = Math::BigFloat->new($n,undef,undef);
201 return $self->bnan() if $nf->is_nan();
203 $self->{_n} = $MBI->_copy( $nf->{_m} ); # get mantissa
205 # now correct $self->{_n} due to $n
206 my $f = Math::BigFloat->new($d,undef,undef);
207 return $self->bnan() if $f->is_nan();
208 $self->{_d} = $MBI->_copy( $f->{_m} );
210 # calculate the difference between nE and dE
211 # XXX TODO: check that exponent() makes a copy to avoid copy()
212 my $diff_e = $nf->exponent()->copy()->bsub( $f->exponent);
213 if ($diff_e->is_negative())
216 $MBI->_lsft( $self->{_d}, $MBI->_new( $diff_e->babs()), 10);
218 elsif (!$diff_e->is_zero())
221 $MBI->_lsft( $self->{_n}, $MBI->_new( $diff_e), 10);
226 # both d and n look like (big)ints
228 $self->{sign} = '+'; # no sign => '+'
231 if ($n =~ /^([+-]?)0*(\d+)\z/) # first part ok?
233 $self->{sign} = $1 || '+'; # no sign => '+'
234 $self->{_n} = $MBI->_new($2 || 0);
237 if ($d =~ /^([+-]?)0*(\d+)\z/) # second part ok?
239 $self->{sign} =~ tr/+-/-+/ if ($1 || '') eq '-'; # negate if second part neg.
240 $self->{_d} = $MBI->_new($2 || 0);
243 if (!defined $self->{_n} || !defined $self->{_d})
245 $d = Math::BigInt->new($d,undef,undef) unless ref $d;
246 $n = Math::BigInt->new($n,undef,undef) unless ref $n;
248 if ($n->{sign} =~ /^[+-]$/ && $d->{sign} =~ /^[+-]$/)
250 # both parts are ok as integers (wierd things like ' 1e0'
251 $self->{_n} = $MBI->_copy($n->{value});
252 $self->{_d} = $MBI->_copy($d->{value});
253 $self->{sign} = $n->{sign};
254 $self->{sign} =~ tr/+-/-+/ if $d->{sign} eq '-'; # -1/-2 => 1/2
255 return $self->bnorm();
258 $self->{sign} = '+'; # a default sign
259 return $self->bnan() if $n->is_nan() || $d->is_nan();
262 if ($n->is_inf() || $d->is_inf())
266 return $self->bnan() if $d->is_inf(); # both are inf => NaN
267 my $s = '+'; # '+inf/+123' or '-inf/-123'
268 $s = '-' if substr($n->{sign},0,1) ne $d->{sign};
270 return $self->binf($s);
273 return $self->bzero();
278 return $self->bnorm();
281 # simple string input
282 if (($n =~ /[\.eE]/))
284 # looks like a float, quacks like a float, so probably is a float
285 $self->{sign} = 'NaN';
286 local $Math::BigFloat::accuracy = undef;
287 local $Math::BigFloat::precision = undef;
288 $self->_new_from_float(Math::BigFloat->new($n,undef,undef));
292 # for simple forms, use $MBI directly
293 if ($n =~ /^([+-]?)0*(\d+)\z/)
295 $self->{sign} = $1 || '+';
296 $self->{_n} = $MBI->_new($2 || 0);
297 $self->{_d} = $MBI->_one();
301 my $n = Math::BigInt->new($n,undef,undef);
302 $self->{_n} = $MBI->_copy($n->{value});
303 $self->{_d} = $MBI->_one();
304 $self->{sign} = $n->{sign};
305 return $self->bnan() if $self->{sign} eq 'NaN';
306 return $self->binf($self->{sign}) if $self->{sign} =~ /^[+-]inf$/;
314 # if two arguments, the first one is the class to "swallow" subclasses
322 return unless ref($x); # only for objects
324 my $self = bless {}, $c;
326 $self->{sign} = $x->{sign};
327 $self->{_d} = $MBI->_copy($x->{_d});
328 $self->{_n} = $MBI->_copy($x->{_n});
329 $self->{_a} = $x->{_a} if defined $x->{_a};
330 $self->{_p} = $x->{_p} if defined $x->{_p};
334 ##############################################################################
338 # return (later set?) configuration data as hash ref
339 my $class = shift || 'Math::BigRat';
341 my $cfg = $class->SUPER::config(@_);
343 # now we need only to override the ones that are different from our parent
344 $cfg->{class} = $class;
349 ##############################################################################
353 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
355 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
357 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
361 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # '+3/2' => '3/2'
363 return $s . $MBI->_str($x->{_n}) if $MBI->_is_one($x->{_d});
364 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
369 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
371 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
373 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
377 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3
378 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
383 # reduce the number to the shortest form
384 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
386 # Both parts must be objects of whatever we are using today.
387 # Second check because Calc.pm has ARRAY res as unblessed objects.
388 if (ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY')
390 require Carp; Carp::croak ("n is not $MBI but (".ref($x->{_n}).') in bnorm()');
392 if (ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY')
394 require Carp; Carp::croak ("d is not $MBI but (".ref($x->{_d}).') in bnorm()');
397 # no normalize for NaN, inf etc.
398 return $x if $x->{sign} !~ /^[+-]$/;
400 # normalize zeros to 0/1
401 if ($MBI->_is_zero($x->{_n}))
403 $x->{sign} = '+'; # never leave a -0
404 $x->{_d} = $MBI->_one() unless $MBI->_is_one($x->{_d});
408 return $x if $MBI->_is_one($x->{_d}); # no need to reduce
410 # reduce other numbers
411 my $gcd = $MBI->_copy($x->{_n});
412 $gcd = $MBI->_gcd($gcd,$x->{_d});
414 if (!$MBI->_is_one($gcd))
416 $x->{_n} = $MBI->_div($x->{_n},$gcd);
417 $x->{_d} = $MBI->_div($x->{_d},$gcd);
422 ##############################################################################
427 # (BRAT or num_str) return BRAT
428 # negate number or make a negated number from string
429 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
431 return $x if $x->modify('bneg');
433 # for +0 dont negate (to have always normalized +0). Does nothing for 'NaN'
434 $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $MBI->_is_zero($x->{_n}));
438 ##############################################################################
443 # used by parent class bnan() to initialize number to NaN
449 my $class = ref($self);
450 # "$self" below will stringify the object, this blows up if $self is a
451 # partial object (happens under trap_nan), so fix it beforehand
452 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
453 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
454 Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
456 $self->{_n} = $MBI->_zero();
457 $self->{_d} = $MBI->_zero();
462 # used by parent class bone() to initialize number to +inf/-inf
468 my $class = ref($self);
469 # "$self" below will stringify the object, this blows up if $self is a
470 # partial object (happens under trap_nan), so fix it beforehand
471 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
472 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
473 Carp::croak ("Tried to set $self to inf in $class\::_binf()");
475 $self->{_n} = $MBI->_zero();
476 $self->{_d} = $MBI->_zero();
481 # used by parent class bone() to initialize number to +1/-1
483 $self->{_n} = $MBI->_one();
484 $self->{_d} = $MBI->_one();
489 # used by parent class bzero() to initialize number to 0
491 $self->{_n} = $MBI->_zero();
492 $self->{_d} = $MBI->_one();
495 ##############################################################################
500 # add two rational numbers
503 my ($self,$x,$y,@r) = (ref($_[0]),@_);
504 # objectify is costly, so avoid it
505 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
507 ($self,$x,$y,@r) = objectify(2,@_);
510 # +inf + +inf => +inf, -inf + -inf => -inf
511 return $x->binf(substr($x->{sign},0,1))
512 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
514 # +inf + -inf or -inf + +inf => NaN
515 return $x->bnan() if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/);
517 # 1 1 gcd(3,4) = 1 1*3 + 1*4 7
518 # - + - = --------- = --
521 # we do not compute the gcd() here, but simple do:
523 # - + - = --------- = --
526 # and bnorm() will then take care of the rest
529 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
532 my $m = $MBI->_mul( $MBI->_copy( $y->{_n} ), $x->{_d} );
535 ($x->{_n}, $x->{sign}) = _e_add( $x->{_n}, $m, $x->{sign}, $y->{sign});
538 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
540 # normalize result, and possible round
541 $x->bnorm()->round(@r);
546 # subtract two rational numbers
549 my ($self,$x,$y,@r) = (ref($_[0]),@_);
550 # objectify is costly, so avoid it
551 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
553 ($self,$x,$y,@r) = objectify(2,@_);
556 # flip sign of $x, call badd(), then flip sign of result
557 $x->{sign} =~ tr/+-/-+/
558 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
559 $x->badd($y,@r); # does norm and round
560 $x->{sign} =~ tr/+-/-+/
561 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
567 # multiply two rational numbers
570 my ($self,$x,$y,@r) = (ref($_[0]),@_);
571 # objectify is costly, so avoid it
572 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
574 ($self,$x,$y,@r) = objectify(2,@_);
577 return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
580 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
582 return $x->bnan() if $x->is_zero() || $y->is_zero();
583 # result will always be +-inf:
584 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
585 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
586 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
587 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
588 return $x->binf('-');
591 # x== 0 # also: or y == 1 or y == -1
592 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
595 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
596 # and reducing in one step. This would save us the bnorm() at the end.
599 # - * - = ----- = - = -
602 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_n});
603 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
606 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
608 $x->bnorm()->round(@r);
613 # (dividend: BRAT or num_str, divisor: BRAT or num_str) return
614 # (BRAT,BRAT) (quo,rem) or BRAT (only rem)
617 my ($self,$x,$y,@r) = (ref($_[0]),@_);
618 # objectify is costly, so avoid it
619 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
621 ($self,$x,$y,@r) = objectify(2,@_);
624 return $self->_div_inf($x,$y)
625 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
627 # x== 0 # also: or y == 1 or y == -1
628 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
630 # XXX TODO: list context, upgrade
631 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
632 # and reducing in one step. This would save us the bnorm() at the end.
638 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
639 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_n});
642 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
644 $x->bnorm()->round(@r);
650 # compute "remainder" (in Perl way) of $x / $y
653 my ($self,$x,$y,@r) = (ref($_[0]),@_);
654 # objectify is costly, so avoid it
655 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
657 ($self,$x,$y,@r) = objectify(2,@_);
660 return $self->_div_inf($x,$y)
661 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
663 return $x if $x->is_zero(); # 0 / 7 = 0, mod 0
665 # compute $x - $y * floor($x/$y), keeping the sign of $x
667 # copy x to u, make it positive and then do a normal division ($u/$y)
668 my $u = bless { sign => '+' }, $self;
669 $u->{_n} = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d} );
670 $u->{_d} = $MBI->_mul( $MBI->_copy($x->{_d}), $y->{_n} );
673 if (! $MBI->_is_one($u->{_d}))
675 $u->{_n} = $MBI->_div($u->{_n},$u->{_d}); # 22/7 => 3/1 w/ truncate
676 # no need to set $u->{_d} to 1, since below we set it to $y->{_d} anyway
679 # now compute $y * $u
680 $u->{_d} = $MBI->_copy($y->{_d}); # 1 * $y->{_d}, see floor above
681 $u->{_n} = $MBI->_mul($u->{_n},$y->{_n});
683 my $xsign = $x->{sign}; $x->{sign} = '+'; # remember sign and make x positive
686 $x->{sign} = $xsign; # put sign back
688 $x->bnorm()->round(@r);
691 ##############################################################################
696 # decrement value (subtract 1)
697 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
699 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
701 if ($x->{sign} eq '-')
703 $x->{_n} = $MBI->_add( $x->{_n}, $x->{_d}); # -5/2 => -7/2
707 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0) # n < d?
710 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
715 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # 5/2 => 3/2
718 $x->bnorm()->round(@r);
723 # increment value (add 1)
724 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
726 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
728 if ($x->{sign} eq '-')
730 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0)
732 # -1/3 ++ => 2/3 (overflow at 0)
733 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
738 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # -5/2 => -3/2
743 $x->{_n} = $MBI->_add($x->{_n},$x->{_d}); # 5/2 => 7/2
745 $x->bnorm()->round(@r);
748 ##############################################################################
749 # is_foo methods (the rest is inherited)
753 # return true if arg (BRAT or num_str) is an integer
754 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
756 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
757 $MBI->_is_one($x->{_d}); # x/y && y != 1 => no integer
763 # return true if arg (BRAT or num_str) is zero
764 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
766 return 1 if $x->{sign} eq '+' && $MBI->_is_zero($x->{_n});
772 # return true if arg (BRAT or num_str) is +1 or -1 if signis given
773 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
775 my $sign = $_[2] || ''; $sign = '+' if $sign ne '-';
777 if ($x->{sign} eq $sign && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}));
783 # return true if arg (BFLOAT or num_str) is odd or false if even
784 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
786 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
787 ($MBI->_is_one($x->{_d}) && $MBI->_is_odd($x->{_n})); # x/2 is not, but 3/1
793 # return true if arg (BINT or num_str) is even or false if odd
794 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
796 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
797 return 1 if ($MBI->_is_one($x->{_d}) # x/3 is never
798 && $MBI->_is_even($x->{_n})); # but 4/1 is
802 ##############################################################################
803 # parts() and friends
807 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
810 return Math::BigInt->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/);
812 my $n = Math::BigInt->new($MBI->_str($x->{_n})); $n->{sign} = $x->{sign};
818 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
821 return Math::BigInt->new($x->{sign}) if $x->{sign} eq 'NaN';
823 return Math::BigInt->bone() if $x->{sign} !~ /^[+-]$/;
825 Math::BigInt->new($MBI->_str($x->{_d}));
830 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
832 my $c = 'Math::BigInt';
834 return ($c->bnan(),$c->bnan()) if $x->{sign} eq 'NaN';
835 return ($c->binf(),$c->binf()) if $x->{sign} eq '+inf';
836 return ($c->binf('-'),$c->binf()) if $x->{sign} eq '-inf';
838 my $n = $c->new( $MBI->_str($x->{_n}));
839 $n->{sign} = $x->{sign};
840 my $d = $c->new( $MBI->_str($x->{_d}));
846 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
848 return $nan unless $x->is_int();
849 $MBI->_len($x->{_n}); # length(-123/1) => length(123)
854 my ($self,$x,$n) = ref($_[0]) ? (undef,$_[0],$_[1]) : objectify(1,@_);
856 return $nan unless $x->is_int();
857 $MBI->_digit($x->{_n},$n || 0); # digit(-123/1,2) => digit(123,2)
860 ##############################################################################
861 # special calc routines
865 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
867 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
868 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
870 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
871 $x->{_d} = $MBI->_one(); # d => 1
872 $x->{_n} = $MBI->_inc($x->{_n})
873 if $x->{sign} eq '+'; # +22/7 => 4/1
874 $x->{sign} = '+' if $MBI->_is_zero($x->{_n}); # -0 => 0
880 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
882 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
883 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
885 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
886 $x->{_d} = $MBI->_one(); # d => 1
887 $x->{_n} = $MBI->_inc($x->{_n})
888 if $x->{sign} eq '-'; # -22/7 => -4/1
894 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
896 # if $x is not an integer
897 if (($x->{sign} ne '+') || (!$MBI->_is_one($x->{_d})))
902 $x->{_n} = $MBI->_fac($x->{_n});
903 # since _d is 1, we don't need to reduce/norm the result
912 my ($self,$x,$y,@r) = (ref($_[0]),@_);
913 # objectify is costly, so avoid it
914 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
916 ($self,$x,$y,@r) = objectify(2,@_);
919 return $x if $x->{sign} =~ /^[+-]inf$/; # -inf/+inf ** x
920 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
921 return $x->bone(@r) if $y->is_zero();
922 return $x->round(@r) if $x->is_one() || $y->is_one();
924 if ($x->{sign} eq '-' && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}))
926 # if $x == -1 and odd/even y => +1/-1
927 return $y->is_odd() ? $x->round(@r) : $x->babs()->round(@r);
928 # my Casio FX-5500L has a bug here: -1 ** 2 is -1, but -1 * -1 is 1;
930 # 1 ** -y => 1 / (1 ** |y|)
931 # so do test for negative $y after above's clause
933 return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0)
935 # shortcut y/1 (and/or x/1)
936 if ($MBI->_is_one($y->{_d}))
938 # shortcut for x/1 and y/1
939 if ($MBI->_is_one($x->{_d}))
941 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # x/1 ** y/1 => (x ** y)/1
942 if ($y->{sign} eq '-')
944 # 0.2 ** -3 => 1/(0.2 ** 3)
945 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
947 # correct sign; + ** + => +
948 if ($x->{sign} eq '-')
950 # - * - => +, - * - * - => -
951 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
953 return $x->round(@r);
956 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # 5/2 ** y/1 => 5 ** y / 2 ** y
957 $x->{_d} = $MBI->_pow($x->{_d},$y->{_n});
958 if ($y->{sign} eq '-')
960 # 0.2 ** -3 => 1/(0.2 ** 3)
961 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
963 # correct sign; + ** + => +
964 if ($x->{sign} eq '-')
966 # - * - => +, - * - * - => -
967 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
969 return $x->round(@r);
972 # regular calculation (this is wrong for d/e ** f/g)
973 my $pow2 = $self->bone();
974 my $y1 = $MBI->_div ( $MBI->_copy($y->{_n}), $y->{_d});
975 my $two = $MBI->_two();
977 while (!$MBI->_is_one($y1))
979 $pow2->bmul($x) if $MBI->_is_odd($y1);
980 $MBI->_div($y1, $two);
983 $x->bmul($pow2) unless $pow2->is_one();
984 # n ** -x => 1/n ** x
985 ($x->{_d},$x->{_n}) = ($x->{_n},$x->{_d}) if $y->{sign} eq '-';
986 $x->bnorm()->round(@r);
992 my ($self,$x,$y,@r) = (ref($_[0]),@_);
994 # objectify is costly, so avoid it
995 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
997 ($self,$x,$y,@r) = objectify(2,$class,@_);
1001 return $x->bzero() if $x->is_one() && $y->{sign} eq '+';
1004 return $x->bnan() if $x->is_zero() || $x->{sign} ne '+' || $y->{sign} ne '+';
1006 if ($x->is_int() && $y->is_int())
1008 return $self->new($x->as_number()->blog($y->as_number(),@r));
1012 $x->_new_from_float( $x->_as_float()->blog(Math::BigFloat->new("$y"),@r) );
1015 sub _float_from_part
1019 my $f = Math::BigFloat->bzero();
1020 $f->{_m} = $MBI->_copy($x);
1021 $f->{_e} = $MBI->_zero();
1030 local $Math::BigFloat::upgrade = undef;
1031 local $Math::BigFloat::accuracy = undef;
1032 local $Math::BigFloat::precision = undef;
1033 # 22/7 => 3.142857143..
1035 my $a = $x->accuracy() || 0;
1036 if ($a != 0 || !$MBI->_is_one($x->{_d}))
1039 return Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}))->bdiv( $MBI->_str($x->{_d}), $x->accuracy());
1042 Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}));
1048 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1049 # objectify is costly, so avoid it
1050 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1052 ($self,$x,$y,@r) = objectify(2,@_);
1055 if ($x->is_int() && $y->is_int())
1057 return $self->new($x->as_number()->broot($y->as_number(),@r));
1061 $x->_new_from_float( $x->_as_float()->broot($y,@r) );
1067 my ($self,$x,$y,$m,@r) = (ref($_[0]),@_);
1068 # objectify is costly, so avoid it
1069 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1071 ($self,$x,$y,$m,@r) = objectify(3,@_);
1074 # $x or $y or $m are NaN or +-inf => NaN
1076 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/ ||
1077 $m->{sign} !~ /^[+-]$/;
1079 if ($x->is_int() && $y->is_int() && $m->is_int())
1081 return $self->new($x->as_number()->bmodpow($y->as_number(),$m,@r));
1084 warn ("bmodpow() not fully implemented");
1091 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1092 # objectify is costly, so avoid it
1093 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1095 ($self,$x,$y,@r) = objectify(2,@_);
1098 # $x or $y are NaN or +-inf => NaN
1100 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
1102 if ($x->is_int() && $y->is_int())
1104 return $self->new($x->as_number()->bmodinv($y->as_number(),@r));
1107 warn ("bmodinv() not fully implemented");
1113 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1115 return $x->bnan() if $x->{sign} !~ /^[+]/; # NaN, -inf or < 0
1116 return $x if $x->{sign} eq '+inf'; # sqrt(inf) == inf
1117 return $x->round(@r) if $x->is_zero() || $x->is_one();
1119 local $Math::BigFloat::upgrade = undef;
1120 local $Math::BigFloat::downgrade = undef;
1121 local $Math::BigFloat::precision = undef;
1122 local $Math::BigFloat::accuracy = undef;
1123 local $Math::BigInt::upgrade = undef;
1124 local $Math::BigInt::precision = undef;
1125 local $Math::BigInt::accuracy = undef;
1127 $x->{_n} = _float_from_part( $x->{_n} )->bsqrt();
1128 $x->{_d} = _float_from_part( $x->{_d} )->bsqrt();
1130 # XXX TODO: we probably can optimze this:
1132 # if sqrt(D) was not integer
1133 if ($x->{_d}->{_es} ne '+')
1135 $x->{_n}->blsft($x->{_d}->exponent()->babs(),10); # 7.1/4.51 => 7.1/45.1
1136 $x->{_d} = $MBI->_copy( $x->{_d}->{_m} ); # 7.1/45.1 => 71/45.1
1138 # if sqrt(N) was not integer
1139 if ($x->{_n}->{_es} ne '+')
1141 $x->{_d}->blsft($x->{_n}->exponent()->babs(),10); # 71/45.1 => 710/45.1
1142 $x->{_n} = $MBI->_copy( $x->{_n}->{_m} ); # 710/45.1 => 710/451
1145 # convert parts to $MBI again
1146 $x->{_n} = $MBI->_lsft( $MBI->_copy( $x->{_n}->{_m} ), $x->{_n}->{_e}, 10)
1147 if ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY';
1148 $x->{_d} = $MBI->_lsft( $MBI->_copy( $x->{_d}->{_m} ), $x->{_d}->{_e}, 10)
1149 if ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY';
1151 $x->bnorm()->round(@r);
1156 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1158 $b = 2 unless defined $b;
1159 $b = $self->new($b) unless ref ($b);
1160 $x->bmul( $b->copy()->bpow($y), @r);
1166 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1168 $b = 2 unless defined $b;
1169 $b = $self->new($b) unless ref ($b);
1170 $x->bdiv( $b->copy()->bpow($y), @r);
1174 ##############################################################################
1192 ##############################################################################
1197 # compare two signed numbers
1200 my ($self,$x,$y) = (ref($_[0]),@_);
1201 # objectify is costly, so avoid it
1202 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1204 ($self,$x,$y) = objectify(2,@_);
1207 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1209 # handle +-inf and NaN
1210 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1211 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1212 return +1 if $x->{sign} eq '+inf';
1213 return -1 if $x->{sign} eq '-inf';
1214 return -1 if $y->{sign} eq '+inf';
1217 # check sign for speed first
1218 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1219 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1222 my $xz = $MBI->_is_zero($x->{_n});
1223 my $yz = $MBI->_is_zero($y->{_n});
1224 return 0 if $xz && $yz; # 0 <=> 0
1225 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
1226 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
1228 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1229 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1231 my $cmp = $MBI->_acmp($t,$u); # signs are equal
1232 $cmp = -$cmp if $x->{sign} eq '-'; # both are '-' => reverse
1238 # compare two numbers (as unsigned)
1241 my ($self,$x,$y) = (ref($_[0]),@_);
1242 # objectify is costly, so avoid it
1243 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1245 ($self,$x,$y) = objectify(2,$class,@_);
1248 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1250 # handle +-inf and NaN
1251 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1252 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
1253 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
1257 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1258 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1259 $MBI->_acmp($t,$u); # ignore signs
1262 ##############################################################################
1263 # output conversation
1267 # convert 17/8 => float (aka 2.125)
1268 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1270 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, NaN, etc
1273 my $neg = ''; $neg = '-' if $x->{sign} eq '-';
1274 return $neg . $MBI->_num($x->{_n}) if $MBI->_is_one($x->{_d});
1276 $x->_as_float()->numify() + 0.0;
1281 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1283 return Math::BigInt->new($x) if $x->{sign} !~ /^[+-]$/; # NaN, inf etc
1285 my $u = Math::BigInt->bzero();
1286 $u->{sign} = $x->{sign};
1287 $u->{value} = $MBI->_div( $MBI->_copy($x->{_n}), $x->{_d}); # 22/7 => 3
1293 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1295 return $x unless $x->is_int();
1297 my $s = $x->{sign}; $s = '' if $s eq '+';
1298 $s . $MBI->_as_bin($x->{_n});
1303 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1305 return $x unless $x->is_int();
1307 my $s = $x->{sign}; $s = '' if $s eq '+';
1308 $s . $MBI->_as_hex($x->{_n});
1311 ##############################################################################
1318 my $lib = ''; my @a;
1320 for ( my $i = 0; $i < $l ; $i++)
1322 if ( $_[$i] eq ':constant' )
1324 # this rest causes overlord er load to step in
1325 overload::constant float => sub { $self->new(shift); };
1327 # elsif ($_[$i] eq 'upgrade')
1329 # # this causes upgrading
1330 # $upgrade = $_[$i+1]; # or undef to disable
1333 elsif ($_[$i] eq 'downgrade')
1335 # this causes downgrading
1336 $downgrade = $_[$i+1]; # or undef to disable
1339 elsif ($_[$i] eq 'lib')
1341 $lib = $_[$i+1] || ''; # default Calc
1344 elsif ($_[$i] eq 'with')
1346 # this argument is no longer used
1347 #$MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
1355 require Math::BigInt;
1357 # let use Math::BigInt lib => 'GMP'; use Math::BigRat; still have GMP
1360 my @c = split /\s*,\s*/, $lib;
1363 $_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
1365 $lib = join(",", @c);
1367 my @import = ('objectify');
1368 push @import, lib => $lib if $lib ne '';
1370 # MBI already loaded, so feed it our lib arguments
1371 Math::BigInt->import( @import );
1373 $MBI = Math::BigFloat->config()->{lib};
1375 # register us with MBI to get notified of future lib changes
1376 Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
1378 # any non :constant stuff is handled by our parent, Exporter (loaded
1379 # by Math::BigFloat, even if @_ is empty, to give it a chance
1380 $self->SUPER::import(@a); # for subclasses
1381 $self->export_to_level(1,$self,@a); # need this, too
1390 Math::BigRat - Arbitrary big rational numbers
1396 my $x = Math::BigRat->new('3/7'); $x += '5/9';
1398 print $x->bstr(),"\n";
1401 my $y = Math::BigRat->new('inf');
1402 print "$y ", ($y->is_inf ? 'is' : 'is not') , " infinity\n";
1404 my $z = Math::BigRat->new(144); $z->bsqrt();
1408 Math::BigRat complements Math::BigInt and Math::BigFloat by providing support
1409 for arbitrary big rational numbers.
1413 Math with the numbers is done (by default) by a module called
1414 Math::BigInt::Calc. This is equivalent to saying:
1416 use Math::BigRat lib => 'Calc';
1418 You can change this by using:
1420 use Math::BigRat lib => 'BitVect';
1422 The following would first try to find Math::BigInt::Foo, then
1423 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
1425 use Math::BigRat lib => 'Foo,Math::BigInt::Bar';
1427 Calc.pm uses as internal format an array of elements of some decimal base
1428 (usually 1e7, but this might be different for some systems) with the least
1429 significant digit first, while BitVect.pm uses a bit vector of base 2, most
1430 significant bit first. Other modules might use even different means of
1431 representing the numbers. See the respective module documentation for further
1434 Currently the following replacement libraries exist, search for them at CPAN:
1436 Math::BigInt::BitVect
1439 Math::BigInt::FastCalc
1443 Any methods not listed here are derived from Math::BigFloat (or
1444 Math::BigInt), so make sure you check these two modules for further
1449 $x = Math::BigRat->new('1/3');
1451 Create a new Math::BigRat object. Input can come in various forms:
1453 $x = Math::BigRat->new(123); # scalars
1454 $x = Math::BigRat->new('inf'); # infinity
1455 $x = Math::BigRat->new('123.3'); # float
1456 $x = Math::BigRat->new('1/3'); # simple string
1457 $x = Math::BigRat->new('1 / 3'); # spaced
1458 $x = Math::BigRat->new('1 / 0.1'); # w/ floats
1459 $x = Math::BigRat->new(Math::BigInt->new(3)); # BigInt
1460 $x = Math::BigRat->new(Math::BigFloat->new('3.1')); # BigFloat
1461 $x = Math::BigRat->new(Math::BigInt::Lite->new('2')); # BigLite
1463 # You can also give D and N as different objects:
1464 $x = Math::BigRat->new(
1465 Math::BigInt->new(-123),
1466 Math::BigInt->new(7),
1471 $n = $x->numerator();
1473 Returns a copy of the numerator (the part above the line) as signed BigInt.
1475 =head2 denominator()
1477 $d = $x->denominator();
1479 Returns a copy of the denominator (the part under the line) as positive BigInt.
1483 ($n,$d) = $x->parts();
1485 Return a list consisting of (signed) numerator and (unsigned) denominator as
1490 $x = Math::BigRat->new('13/7');
1491 print $x->as_int(),"\n"; # '1'
1493 Returns a copy of the object as BigInt, truncated to an integer.
1495 C<as_number()> is an alias for C<as_int()>.
1499 $x = Math::BigRat->new('13');
1500 print $x->as_hex(),"\n"; # '0xd'
1502 Returns the BigRat as hexadecimal string. Works only for integers.
1506 $x = Math::BigRat->new('13');
1507 print $x->as_bin(),"\n"; # '0x1101'
1509 Returns the BigRat as binary string. Works only for integers.
1515 Calculates the factorial of $x. For instance:
1517 print Math::BigRat->new('3/1')->bfac(),"\n"; # 1*2*3
1518 print Math::BigRat->new('5/1')->bfac(),"\n"; # 1*2*3*4*5
1520 Works currently only for integers.
1524 Is not yet implemented.
1526 =head2 bround()/round()/bfround()
1528 Are not yet implemented.
1533 my $x = Math::BigRat->new('7/4');
1534 my $y = Math::BigRat->new('4/3');
1537 Set $x to the remainder of the division of $x by $y.
1541 print "$x is 1\n" if $x->is_one();
1543 Return true if $x is exactly one, otherwise false.
1547 print "$x is 0\n" if $x->is_zero();
1549 Return true if $x is exactly zero, otherwise false.
1553 print "$x is >= 0\n" if $x->is_positive();
1555 Return true if $x is positive (greater than or equal to zero), otherwise
1556 false. Please note that '+inf' is also positive, while 'NaN' and '-inf' aren't.
1558 C<is_positive()> is an alias for C<is_pos()>.
1562 print "$x is < 0\n" if $x->is_negative();
1564 Return true if $x is negative (smaller than zero), otherwise false. Please
1565 note that '-inf' is also negative, while 'NaN' and '+inf' aren't.
1567 C<is_negative()> is an alias for C<is_neg()>.
1571 print "$x is an integer\n" if $x->is_int();
1573 Return true if $x has a denominator of 1 (e.g. no fraction parts), otherwise
1574 false. Please note that '-inf', 'inf' and 'NaN' aren't integer.
1578 print "$x is odd\n" if $x->is_odd();
1580 Return true if $x is odd, otherwise false.
1584 print "$x is even\n" if $x->is_even();
1586 Return true if $x is even, otherwise false.
1592 Set $x to the next bigger integer value (e.g. truncate the number to integer
1593 and then increment it by one).
1599 Truncate $x to an integer value.
1605 Calculate the square root of $x.
1611 print Dumper ( Math::BigRat->config() );
1612 print Math::BigRat->config()->{lib},"\n";
1614 Returns a hash containing the configuration, e.g. the version number, lib
1615 loaded etc. The following hash keys are currently filled in with the
1616 appropriate information.
1618 key RO/RW Description
1620 ============================================================
1621 lib RO Name of the Math library
1623 lib_version RO Version of 'lib'
1625 class RO The class of config you just called
1627 version RO version number of the class you used
1629 upgrade RW To which class numbers are upgraded
1631 downgrade RW To which class numbers are downgraded
1633 precision RW Global precision
1635 accuracy RW Global accuracy
1637 round_mode RW Global round mode
1639 div_scale RW Fallback accuracy for div
1641 trap_nan RW Trap creation of NaN (undef = no)
1643 trap_inf RW Trap creation of +inf/-inf (undef = no)
1646 By passing a reference to a hash you may set the configuration values. This
1647 works only for values that a marked with a C<RW> above, anything else is
1652 Some things are not yet implemented, or only implemented half-way:
1656 =item inf handling (partial)
1658 =item NaN handling (partial)
1660 =item rounding (not implemented except for bceil/bfloor)
1662 =item $x ** $y where $y is not an integer
1664 =item bmod(), blog(), bmodinv() and bmodpow() (partial)
1670 This program is free software; you may redistribute it and/or modify it under
1671 the same terms as Perl itself.
1675 L<Math::BigFloat> and L<Math::Big> as well as L<Math::BigInt::BitVect>,
1676 L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
1678 See L<http://search.cpan.org/search?dist=bignum> for a way to use
1681 The package at L<http://search.cpan.org/search?dist=Math%3A%3ABigRat>
1682 may contain more documentation and examples as well as testcases.
1686 (C) by Tels L<http://bloodgate.com/> 2001 - 2005.