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.
16 # anythig older is untested, and unlikely to work
21 use vars qw($VERSION @ISA $upgrade $downgrade
22 $accuracy $precision $round_mode $div_scale $_trap_nan $_trap_inf);
24 @ISA = qw(Math::BigFloat);
28 use overload; # inherit overload from Math::BigFloat
32 *objectify = \&Math::BigInt::objectify; # inherit this from BigInt
33 *AUTOLOAD = \&Math::BigFloat::AUTOLOAD; # can't inherit AUTOLOAD
34 # we inherit these from BigFloat because currently it is not possible
35 # that MBF has a different $MBI variable than we, because MBF also uses
36 # Math::BigInt::config->('lib'); (there is always only one library loaded)
37 *_e_add = \&Math::BigFloat::_e_add;
38 *_e_sub = \&Math::BigFloat::_e_sub;
39 *as_int = \&as_number;
40 *is_pos = \&is_positive;
41 *is_neg = \&is_negative;
44 ##############################################################################
45 # Global constants and flags. Access these only via the accessor methods!
47 $accuracy = $precision = undef;
53 # These are internally, and not to be used from the outside at all!
55 $_trap_nan = 0; # are NaNs ok? set w/ config()
56 $_trap_inf = 0; # are infs ok? set w/ config()
58 # the package we are using for our private parts, defaults to:
59 # Math::BigInt->config()->{lib}
60 my $MBI = 'Math::BigInt::Calc';
63 my $class = 'Math::BigRat';
67 return 0 if $_[1] =~ /^Math::Big(Int|Float)/; # we aren't
71 ##############################################################################
75 # turn a single float input into a rational number (like '0.1')
78 return $self->bnan() if $f->is_nan();
79 return $self->binf($f->{sign}) if $f->{sign} =~ /^[+-]inf$/;
81 $self->{_n} = $MBI->_copy( $f->{_m} ); # mantissa
82 $self->{_d} = $MBI->_one();
83 $self->{sign} = $f->{sign} || '+';
86 # something like Math::BigRat->new('0.1');
88 $MBI->_lsft ( $self->{_d}, $f->{_e} ,10);
92 # something like Math::BigRat->new('10');
94 $MBI->_lsft ( $self->{_n}, $f->{_e} ,10) unless
95 $MBI->_is_zero($f->{_e});
102 # create a Math::BigRat
107 my $self = { }; bless $self,$class;
109 # input like (BigInt) or (BigFloat):
110 if ((!defined $d) && (ref $n) && (!$n->isa('Math::BigRat')))
112 if ($n->isa('Math::BigFloat'))
114 $self->_new_from_float($n);
116 if ($n->isa('Math::BigInt'))
118 # TODO: trap NaN, inf
119 $self->{_n} = $MBI->_copy($n->{value}); # "mantissa" = N
120 $self->{_d} = $MBI->_one(); # d => 1
121 $self->{sign} = $n->{sign};
123 if ($n->isa('Math::BigInt::Lite'))
125 # TODO: trap NaN, inf
126 $self->{sign} = '+'; $self->{sign} = '-' if $$n < 0;
127 $self->{_n} = $MBI->_new(abs($$n)); # "mantissa" = N
128 $self->{_d} = $MBI->_one(); # d => 1
130 return $self->bnorm(); # normalize (120/1 => 12/10)
133 # input like (BigInt,BigInt) or (BigLite,BigLite):
134 if (ref($d) && ref($n))
136 # do N first (for $self->{sign}):
137 if ($n->isa('Math::BigInt'))
139 # TODO: trap NaN, inf
140 $self->{_n} = $MBI->_copy($n->{value}); # "mantissa" = N
141 $self->{sign} = $n->{sign};
143 elsif ($n->isa('Math::BigInt::Lite'))
145 # TODO: trap NaN, inf
146 $self->{sign} = '+'; $self->{sign} = '-' if $$n < 0;
147 $self->{_n} = $MBI->_new(abs($$n)); # "mantissa" = $n
152 Carp::croak(ref($n) . " is not a recognized object format for Math::BigRat->new");
155 if ($d->isa('Math::BigInt'))
157 # TODO: trap NaN, inf
158 $self->{_d} = $MBI->_copy($d->{value}); # "mantissa" = D
159 # +/+ or -/- => +, +/- or -/+ => -
160 $self->{sign} = $d->{sign} ne $self->{sign} ? '-' : '+';
162 elsif ($d->isa('Math::BigInt::Lite'))
164 # TODO: trap NaN, inf
165 $self->{_d} = $MBI->_new(abs($$d)); # "mantissa" = D
166 my $ds = '+'; $ds = '-' if $$d < 0;
167 # +/+ or -/- => +, +/- or -/+ => -
168 $self->{sign} = $ds ne $self->{sign} ? '-' : '+';
173 Carp::croak(ref($d) . " is not a recognized object format for Math::BigRat->new");
175 return $self->bnorm(); # normalize (120/1 => 12/10)
177 return $n->copy() if ref $n; # already a BigRat
181 $self->{_n} = $MBI->_zero(); # undef => 0
182 $self->{_d} = $MBI->_one();
187 # string input with / delimiter
188 if ($n =~ /\s*\/\s*/)
190 return $class->bnan() if $n =~ /\/.*\//; # 1/2/3 isn't valid
191 return $class->bnan() if $n =~ /\/\s*$/; # 1/ isn't valid
192 ($n,$d) = split (/\//,$n);
193 # try as BigFloats first
194 if (($n =~ /[\.eE]/) || ($d =~ /[\.eE]/))
196 local $Math::BigFloat::accuracy = undef;
197 local $Math::BigFloat::precision = undef;
199 # one of them looks like a float
200 my $nf = Math::BigFloat->new($n,undef,undef);
202 return $self->bnan() if $nf->is_nan();
204 $self->{_n} = $MBI->_copy( $nf->{_m} ); # get mantissa
206 # now correct $self->{_n} due to $n
207 my $f = Math::BigFloat->new($d,undef,undef);
208 return $self->bnan() if $f->is_nan();
209 $self->{_d} = $MBI->_copy( $f->{_m} );
211 # calculate the difference between nE and dE
212 my $diff_e = $nf->exponent()->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*([0-9]+)\z/) # first part ok?
233 $self->{sign} = $1 || '+'; # no sign => '+'
234 $self->{_n} = $MBI->_new($2 || 0);
237 if ($d =~ /^([+-]?)0*([0-9]+)\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*([0-9]+)\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 if ( my $c = $MBI->_check($x->{_n}) )
389 require Carp; Carp::croak ("n did not pass the self-check ($c) in bnorm()");
391 if ( my $c = $MBI->_check($x->{_d}) )
393 require Carp; Carp::croak ("d did not pass the self-check ($c) in bnorm()");
396 # no normalize for NaN, inf etc.
397 return $x if $x->{sign} !~ /^[+-]$/;
399 # normalize zeros to 0/1
400 if ($MBI->_is_zero($x->{_n}))
402 $x->{sign} = '+'; # never leave a -0
403 $x->{_d} = $MBI->_one() unless $MBI->_is_one($x->{_d});
407 return $x if $MBI->_is_one($x->{_d}); # no need to reduce
409 # reduce other numbers
410 my $gcd = $MBI->_copy($x->{_n});
411 $gcd = $MBI->_gcd($gcd,$x->{_d});
413 if (!$MBI->_is_one($gcd))
415 $x->{_n} = $MBI->_div($x->{_n},$gcd);
416 $x->{_d} = $MBI->_div($x->{_d},$gcd);
421 ##############################################################################
426 # (BRAT or num_str) return BRAT
427 # negate number or make a negated number from string
428 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
430 return $x if $x->modify('bneg');
432 # for +0 dont negate (to have always normalized +0). Does nothing for 'NaN'
433 $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $MBI->_is_zero($x->{_n}));
437 ##############################################################################
442 # used by parent class bnan() to initialize number to NaN
448 my $class = ref($self);
449 # "$self" below will stringify the object, this blows up if $self is a
450 # partial object (happens under trap_nan), so fix it beforehand
451 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
452 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
453 Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
455 $self->{_n} = $MBI->_zero();
456 $self->{_d} = $MBI->_zero();
461 # used by parent class bone() to initialize number to +inf/-inf
467 my $class = ref($self);
468 # "$self" below will stringify the object, this blows up if $self is a
469 # partial object (happens under trap_nan), so fix it beforehand
470 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
471 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
472 Carp::croak ("Tried to set $self to inf in $class\::_binf()");
474 $self->{_n} = $MBI->_zero();
475 $self->{_d} = $MBI->_zero();
480 # used by parent class bone() to initialize number to +1/-1
482 $self->{_n} = $MBI->_one();
483 $self->{_d} = $MBI->_one();
488 # used by parent class bzero() to initialize number to 0
490 $self->{_n} = $MBI->_zero();
491 $self->{_d} = $MBI->_one();
494 ##############################################################################
499 # add two rational numbers
502 my ($self,$x,$y,@r) = (ref($_[0]),@_);
503 # objectify is costly, so avoid it
504 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
506 ($self,$x,$y,@r) = objectify(2,@_);
509 # +inf + +inf => +inf, -inf + -inf => -inf
510 return $x->binf(substr($x->{sign},0,1))
511 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
513 # +inf + -inf or -inf + +inf => NaN
514 return $x->bnan() if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/);
516 # 1 1 gcd(3,4) = 1 1*3 + 1*4 7
517 # - + - = --------- = --
520 # we do not compute the gcd() here, but simple do:
522 # - + - = --------- = --
525 # and bnorm() will then take care of the rest
528 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
531 my $m = $MBI->_mul( $MBI->_copy( $y->{_n} ), $x->{_d} );
534 ($x->{_n}, $x->{sign}) = _e_add( $x->{_n}, $m, $x->{sign}, $y->{sign});
537 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
539 # normalize result, and possible round
540 $x->bnorm()->round(@r);
545 # subtract two rational numbers
548 my ($self,$x,$y,@r) = (ref($_[0]),@_);
549 # objectify is costly, so avoid it
550 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
552 ($self,$x,$y,@r) = objectify(2,@_);
555 # flip sign of $x, call badd(), then flip sign of result
556 $x->{sign} =~ tr/+-/-+/
557 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
558 $x->badd($y,@r); # does norm and round
559 $x->{sign} =~ tr/+-/-+/
560 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
566 # multiply two rational numbers
569 my ($self,$x,$y,@r) = (ref($_[0]),@_);
570 # objectify is costly, so avoid it
571 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
573 ($self,$x,$y,@r) = objectify(2,@_);
576 return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
579 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
581 return $x->bnan() if $x->is_zero() || $y->is_zero();
582 # result will always be +-inf:
583 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
584 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
585 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
586 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
587 return $x->binf('-');
590 # x== 0 # also: or y == 1 or y == -1
591 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
594 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
595 # and reducing in one step. This would save us the bnorm() at the end.
598 # - * - = ----- = - = -
601 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_n});
602 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
605 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
607 $x->bnorm()->round(@r);
612 # (dividend: BRAT or num_str, divisor: BRAT or num_str) return
613 # (BRAT,BRAT) (quo,rem) or BRAT (only rem)
616 my ($self,$x,$y,@r) = (ref($_[0]),@_);
617 # objectify is costly, so avoid it
618 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
620 ($self,$x,$y,@r) = objectify(2,@_);
623 return $self->_div_inf($x,$y)
624 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
626 # x== 0 # also: or y == 1 or y == -1
627 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
629 # XXX TODO: list context, upgrade
630 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
631 # and reducing in one step. This would save us the bnorm() at the end.
637 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
638 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_n});
641 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
643 $x->bnorm()->round(@r);
649 # compute "remainder" (in Perl way) of $x / $y
652 my ($self,$x,$y,@r) = (ref($_[0]),@_);
653 # objectify is costly, so avoid it
654 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
656 ($self,$x,$y,@r) = objectify(2,@_);
659 return $self->_div_inf($x,$y)
660 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
662 return $x if $x->is_zero(); # 0 / 7 = 0, mod 0
664 # compute $x - $y * floor($x/$y), keeping the sign of $x
666 # copy x to u, make it positive and then do a normal division ($u/$y)
667 my $u = bless { sign => '+' }, $self;
668 $u->{_n} = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d} );
669 $u->{_d} = $MBI->_mul( $MBI->_copy($x->{_d}), $y->{_n} );
672 if (! $MBI->_is_one($u->{_d}))
674 $u->{_n} = $MBI->_div($u->{_n},$u->{_d}); # 22/7 => 3/1 w/ truncate
675 # no need to set $u->{_d} to 1, since below we set it to $y->{_d} anyway
678 # now compute $y * $u
679 $u->{_d} = $MBI->_copy($y->{_d}); # 1 * $y->{_d}, see floor above
680 $u->{_n} = $MBI->_mul($u->{_n},$y->{_n});
682 my $xsign = $x->{sign}; $x->{sign} = '+'; # remember sign and make x positive
685 $x->{sign} = $xsign; # put sign back
687 $x->bnorm()->round(@r);
690 ##############################################################################
695 # decrement value (subtract 1)
696 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
698 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
700 if ($x->{sign} eq '-')
702 $x->{_n} = $MBI->_add( $x->{_n}, $x->{_d}); # -5/2 => -7/2
706 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0) # n < d?
709 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
714 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # 5/2 => 3/2
717 $x->bnorm()->round(@r);
722 # increment value (add 1)
723 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
725 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
727 if ($x->{sign} eq '-')
729 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0)
731 # -1/3 ++ => 2/3 (overflow at 0)
732 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
737 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # -5/2 => -3/2
742 $x->{_n} = $MBI->_add($x->{_n},$x->{_d}); # 5/2 => 7/2
744 $x->bnorm()->round(@r);
747 ##############################################################################
748 # is_foo methods (the rest is inherited)
752 # return true if arg (BRAT or num_str) is an integer
753 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
755 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
756 $MBI->_is_one($x->{_d}); # x/y && y != 1 => no integer
762 # return true if arg (BRAT or num_str) is zero
763 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
765 return 1 if $x->{sign} eq '+' && $MBI->_is_zero($x->{_n});
771 # return true if arg (BRAT or num_str) is +1 or -1 if signis given
772 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
774 my $sign = $_[2] || ''; $sign = '+' if $sign ne '-';
776 if ($x->{sign} eq $sign && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}));
782 # return true if arg (BFLOAT or num_str) is odd or false if even
783 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
785 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
786 ($MBI->_is_one($x->{_d}) && $MBI->_is_odd($x->{_n})); # x/2 is not, but 3/1
792 # return true if arg (BINT or num_str) is even or false if odd
793 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
795 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
796 return 1 if ($MBI->_is_one($x->{_d}) # x/3 is never
797 && $MBI->_is_even($x->{_n})); # but 4/1 is
801 ##############################################################################
802 # parts() and friends
806 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
809 return Math::BigInt->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/);
811 my $n = Math::BigInt->new($MBI->_str($x->{_n})); $n->{sign} = $x->{sign};
817 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
820 return Math::BigInt->new($x->{sign}) if $x->{sign} eq 'NaN';
822 return Math::BigInt->bone() if $x->{sign} !~ /^[+-]$/;
824 Math::BigInt->new($MBI->_str($x->{_d}));
829 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
831 my $c = 'Math::BigInt';
833 return ($c->bnan(),$c->bnan()) if $x->{sign} eq 'NaN';
834 return ($c->binf(),$c->binf()) if $x->{sign} eq '+inf';
835 return ($c->binf('-'),$c->binf()) if $x->{sign} eq '-inf';
837 my $n = $c->new( $MBI->_str($x->{_n}));
838 $n->{sign} = $x->{sign};
839 my $d = $c->new( $MBI->_str($x->{_d}));
845 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
847 return $nan unless $x->is_int();
848 $MBI->_len($x->{_n}); # length(-123/1) => length(123)
853 my ($self,$x,$n) = ref($_[0]) ? (undef,$_[0],$_[1]) : objectify(1,@_);
855 return $nan unless $x->is_int();
856 $MBI->_digit($x->{_n},$n || 0); # digit(-123/1,2) => digit(123,2)
859 ##############################################################################
860 # special calc routines
864 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
866 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
867 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
869 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
870 $x->{_d} = $MBI->_one(); # d => 1
871 $x->{_n} = $MBI->_inc($x->{_n})
872 if $x->{sign} eq '+'; # +22/7 => 4/1
873 $x->{sign} = '+' if $MBI->_is_zero($x->{_n}); # -0 => 0
879 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
881 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
882 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
884 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
885 $x->{_d} = $MBI->_one(); # d => 1
886 $x->{_n} = $MBI->_inc($x->{_n})
887 if $x->{sign} eq '-'; # -22/7 => -4/1
893 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
895 # if $x is not an integer
896 if (($x->{sign} ne '+') || (!$MBI->_is_one($x->{_d})))
901 $x->{_n} = $MBI->_fac($x->{_n});
902 # since _d is 1, we don't need to reduce/norm the result
911 my ($self,$x,$y,@r) = (ref($_[0]),@_);
912 # objectify is costly, so avoid it
913 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
915 ($self,$x,$y,@r) = objectify(2,@_);
918 return $x if $x->{sign} =~ /^[+-]inf$/; # -inf/+inf ** x
919 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
920 return $x->bone(@r) if $y->is_zero();
921 return $x->round(@r) if $x->is_one() || $y->is_one();
923 if ($x->{sign} eq '-' && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}))
925 # if $x == -1 and odd/even y => +1/-1
926 return $y->is_odd() ? $x->round(@r) : $x->babs()->round(@r);
927 # my Casio FX-5500L has a bug here: -1 ** 2 is -1, but -1 * -1 is 1;
929 # 1 ** -y => 1 / (1 ** |y|)
930 # so do test for negative $y after above's clause
932 return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0)
934 # shortcut y/1 (and/or x/1)
935 if ($MBI->_is_one($y->{_d}))
937 # shortcut for x/1 and y/1
938 if ($MBI->_is_one($x->{_d}))
940 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # x/1 ** y/1 => (x ** y)/1
941 if ($y->{sign} eq '-')
943 # 0.2 ** -3 => 1/(0.2 ** 3)
944 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
946 # correct sign; + ** + => +
947 if ($x->{sign} eq '-')
949 # - * - => +, - * - * - => -
950 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
952 return $x->round(@r);
955 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # 5/2 ** y/1 => 5 ** y / 2 ** y
956 $x->{_d} = $MBI->_pow($x->{_d},$y->{_n});
957 if ($y->{sign} eq '-')
959 # 0.2 ** -3 => 1/(0.2 ** 3)
960 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
962 # correct sign; + ** + => +
963 if ($x->{sign} eq '-')
965 # - * - => +, - * - * - => -
966 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
968 return $x->round(@r);
971 # regular calculation (this is wrong for d/e ** f/g)
972 my $pow2 = $self->bone();
973 my $y1 = $MBI->_div ( $MBI->_copy($y->{_n}), $y->{_d});
974 my $two = $MBI->_two();
976 while (!$MBI->_is_one($y1))
978 $pow2->bmul($x) if $MBI->_is_odd($y1);
979 $MBI->_div($y1, $two);
982 $x->bmul($pow2) unless $pow2->is_one();
983 # n ** -x => 1/n ** x
984 ($x->{_d},$x->{_n}) = ($x->{_n},$x->{_d}) if $y->{sign} eq '-';
985 $x->bnorm()->round(@r);
991 my ($self,$x,$y,@r) = (ref($_[0]),@_);
993 # objectify is costly, so avoid it
994 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
996 ($self,$x,$y,@r) = objectify(2,$class,@_);
1000 return $x->bzero() if $x->is_one() && $y->{sign} eq '+';
1003 return $x->bnan() if $x->is_zero() || $x->{sign} ne '+' || $y->{sign} ne '+';
1005 if ($x->is_int() && $y->is_int())
1007 return $self->new($x->as_number()->blog($y->as_number(),@r));
1011 $x->_new_from_float( $x->_as_float()->blog(Math::BigFloat->new("$y"),@r) );
1014 sub _float_from_part
1018 my $f = Math::BigFloat->bzero();
1019 $f->{_m} = $MBI->_copy($x);
1020 $f->{_e} = $MBI->_zero();
1029 local $Math::BigFloat::upgrade = undef;
1030 local $Math::BigFloat::accuracy = undef;
1031 local $Math::BigFloat::precision = undef;
1032 # 22/7 => 3.142857143..
1034 my $a = $x->accuracy() || 0;
1035 if ($a != 0 || !$MBI->_is_one($x->{_d}))
1038 return Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}))->bdiv( $MBI->_str($x->{_d}), $x->accuracy());
1041 Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}));
1047 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1048 # objectify is costly, so avoid it
1049 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1051 ($self,$x,$y,@r) = objectify(2,@_);
1054 if ($x->is_int() && $y->is_int())
1056 return $self->new($x->as_number()->broot($y->as_number(),@r));
1060 $x->_new_from_float( $x->_as_float()->broot($y,@r) );
1066 my ($self,$x,$y,$m,@r) = (ref($_[0]),@_);
1067 # objectify is costly, so avoid it
1068 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1070 ($self,$x,$y,$m,@r) = objectify(3,@_);
1073 # $x or $y or $m are NaN or +-inf => NaN
1075 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/ ||
1076 $m->{sign} !~ /^[+-]$/;
1078 if ($x->is_int() && $y->is_int() && $m->is_int())
1080 return $self->new($x->as_number()->bmodpow($y->as_number(),$m,@r));
1083 warn ("bmodpow() not fully implemented");
1090 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1091 # objectify is costly, so avoid it
1092 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1094 ($self,$x,$y,@r) = objectify(2,@_);
1097 # $x or $y are NaN or +-inf => NaN
1099 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
1101 if ($x->is_int() && $y->is_int())
1103 return $self->new($x->as_number()->bmodinv($y->as_number(),@r));
1106 warn ("bmodinv() not fully implemented");
1112 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1114 return $x->bnan() if $x->{sign} !~ /^[+]/; # NaN, -inf or < 0
1115 return $x if $x->{sign} eq '+inf'; # sqrt(inf) == inf
1116 return $x->round(@r) if $x->is_zero() || $x->is_one();
1118 local $Math::BigFloat::upgrade = undef;
1119 local $Math::BigFloat::downgrade = undef;
1120 local $Math::BigFloat::precision = undef;
1121 local $Math::BigFloat::accuracy = undef;
1122 local $Math::BigInt::upgrade = undef;
1123 local $Math::BigInt::precision = undef;
1124 local $Math::BigInt::accuracy = undef;
1126 $x->{_n} = _float_from_part( $x->{_n} )->bsqrt();
1127 $x->{_d} = _float_from_part( $x->{_d} )->bsqrt();
1129 # XXX TODO: we probably can optimze this:
1131 # if sqrt(D) was not integer
1132 if ($x->{_d}->{_es} ne '+')
1134 $x->{_n}->blsft($x->{_d}->exponent()->babs(),10); # 7.1/4.51 => 7.1/45.1
1135 $x->{_d} = $MBI->_copy( $x->{_d}->{_m} ); # 7.1/45.1 => 71/45.1
1137 # if sqrt(N) was not integer
1138 if ($x->{_n}->{_es} ne '+')
1140 $x->{_d}->blsft($x->{_n}->exponent()->babs(),10); # 71/45.1 => 710/45.1
1141 $x->{_n} = $MBI->_copy( $x->{_n}->{_m} ); # 710/45.1 => 710/451
1144 # convert parts to $MBI again
1145 $x->{_n} = $MBI->_lsft( $MBI->_copy( $x->{_n}->{_m} ), $x->{_n}->{_e}, 10)
1146 if ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY';
1147 $x->{_d} = $MBI->_lsft( $MBI->_copy( $x->{_d}->{_m} ), $x->{_d}->{_e}, 10)
1148 if ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY';
1150 $x->bnorm()->round(@r);
1155 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1157 $b = 2 unless defined $b;
1158 $b = $self->new($b) unless ref ($b);
1159 $x->bmul( $b->copy()->bpow($y), @r);
1165 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1167 $b = 2 unless defined $b;
1168 $b = $self->new($b) unless ref ($b);
1169 $x->bdiv( $b->copy()->bpow($y), @r);
1173 ##############################################################################
1191 ##############################################################################
1196 # compare two signed numbers
1199 my ($self,$x,$y) = (ref($_[0]),@_);
1200 # objectify is costly, so avoid it
1201 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1203 ($self,$x,$y) = objectify(2,@_);
1206 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1208 # handle +-inf and NaN
1209 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1210 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1211 return +1 if $x->{sign} eq '+inf';
1212 return -1 if $x->{sign} eq '-inf';
1213 return -1 if $y->{sign} eq '+inf';
1216 # check sign for speed first
1217 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1218 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1221 my $xz = $MBI->_is_zero($x->{_n});
1222 my $yz = $MBI->_is_zero($y->{_n});
1223 return 0 if $xz && $yz; # 0 <=> 0
1224 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
1225 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
1227 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1228 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1230 my $cmp = $MBI->_acmp($t,$u); # signs are equal
1231 $cmp = -$cmp if $x->{sign} eq '-'; # both are '-' => reverse
1237 # compare two numbers (as unsigned)
1240 my ($self,$x,$y) = (ref($_[0]),@_);
1241 # objectify is costly, so avoid it
1242 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1244 ($self,$x,$y) = objectify(2,$class,@_);
1247 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1249 # handle +-inf and NaN
1250 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1251 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
1252 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
1256 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1257 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1258 $MBI->_acmp($t,$u); # ignore signs
1261 ##############################################################################
1262 # output conversation
1266 # convert 17/8 => float (aka 2.125)
1267 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1269 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, NaN, etc
1272 my $neg = ''; $neg = '-' if $x->{sign} eq '-';
1273 return $neg . $MBI->_num($x->{_n}) if $MBI->_is_one($x->{_d});
1275 $x->_as_float()->numify() + 0.0;
1280 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1282 return Math::BigInt->new($x) if $x->{sign} !~ /^[+-]$/; # NaN, inf etc
1284 my $u = Math::BigInt->bzero();
1285 $u->{sign} = $x->{sign};
1286 $u->{value} = $MBI->_div( $MBI->_copy($x->{_n}), $x->{_d}); # 22/7 => 3
1292 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1294 return $x unless $x->is_int();
1296 my $s = $x->{sign}; $s = '' if $s eq '+';
1297 $s . $MBI->_as_bin($x->{_n});
1302 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1304 return $x unless $x->is_int();
1306 my $s = $x->{sign}; $s = '' if $s eq '+';
1307 $s . $MBI->_as_hex($x->{_n});
1312 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1314 return $x unless $x->is_int();
1316 my $s = $x->{sign}; $s = '' if $s eq '+';
1317 $s . $MBI->_as_oct($x->{_n});
1320 ##############################################################################
1343 push @parts, Math::BigInt->from_oct($c);
1345 $class->new ( @parts );
1348 ##############################################################################
1355 my $lib = ''; my @a;
1358 for ( my $i = 0; $i < $l ; $i++)
1360 if ( $_[$i] eq ':constant' )
1362 # this rest causes overlord er load to step in
1363 overload::constant float => sub { $self->new(shift); };
1365 # elsif ($_[$i] eq 'upgrade')
1367 # # this causes upgrading
1368 # $upgrade = $_[$i+1]; # or undef to disable
1371 elsif ($_[$i] eq 'downgrade')
1373 # this causes downgrading
1374 $downgrade = $_[$i+1]; # or undef to disable
1377 elsif ($_[$i] =~ /^(lib|try|only)\z/)
1379 $lib = $_[$i+1] || ''; # default Calc
1380 $try = $1; # lib, try or only
1383 elsif ($_[$i] eq 'with')
1385 # this argument is no longer used
1386 #$MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
1394 require Math::BigInt;
1396 # let use Math::BigInt lib => 'GMP'; use Math::BigRat; still have GMP
1399 my @c = split /\s*,\s*/, $lib;
1402 $_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
1404 $lib = join(",", @c);
1406 my @import = ('objectify');
1407 push @import, $try => $lib if $lib ne '';
1409 # MBI already loaded, so feed it our lib arguments
1410 Math::BigInt->import( @import );
1412 $MBI = Math::BigFloat->config()->{lib};
1414 # register us with MBI to get notified of future lib changes
1415 Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
1417 # any non :constant stuff is handled by our parent, Exporter (loaded
1418 # by Math::BigFloat, even if @_ is empty, to give it a chance
1419 $self->SUPER::import(@a); # for subclasses
1420 $self->export_to_level(1,$self,@a); # need this, too
1429 Math::BigRat - Arbitrary big rational numbers
1435 my $x = Math::BigRat->new('3/7'); $x += '5/9';
1437 print $x->bstr(),"\n";
1440 my $y = Math::BigRat->new('inf');
1441 print "$y ", ($y->is_inf ? 'is' : 'is not') , " infinity\n";
1443 my $z = Math::BigRat->new(144); $z->bsqrt();
1447 Math::BigRat complements Math::BigInt and Math::BigFloat by providing support
1448 for arbitrary big rational numbers.
1452 You can change the underlying module that does the low-level
1453 math operations by using:
1455 use Math::BigRat try => 'GMP';
1457 Note: This needs Math::BigInt::GMP installed.
1459 The following would first try to find Math::BigInt::Foo, then
1460 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
1462 use Math::BigRat try => 'Foo,Math::BigInt::Bar';
1464 If you want to get warned when the fallback occurs, replace "try" with
1467 use Math::BigRat lib => 'Foo,Math::BigInt::Bar';
1469 If you want the code to die instead, replace "try" with
1472 use Math::BigRat only => 'Foo,Math::BigInt::Bar';
1476 Any methods not listed here are derived from Math::BigFloat (or
1477 Math::BigInt), so make sure you check these two modules for further
1482 $x = Math::BigRat->new('1/3');
1484 Create a new Math::BigRat object. Input can come in various forms:
1486 $x = Math::BigRat->new(123); # scalars
1487 $x = Math::BigRat->new('inf'); # infinity
1488 $x = Math::BigRat->new('123.3'); # float
1489 $x = Math::BigRat->new('1/3'); # simple string
1490 $x = Math::BigRat->new('1 / 3'); # spaced
1491 $x = Math::BigRat->new('1 / 0.1'); # w/ floats
1492 $x = Math::BigRat->new(Math::BigInt->new(3)); # BigInt
1493 $x = Math::BigRat->new(Math::BigFloat->new('3.1')); # BigFloat
1494 $x = Math::BigRat->new(Math::BigInt::Lite->new('2')); # BigLite
1496 # You can also give D and N as different objects:
1497 $x = Math::BigRat->new(
1498 Math::BigInt->new(-123),
1499 Math::BigInt->new(7),
1504 $n = $x->numerator();
1506 Returns a copy of the numerator (the part above the line) as signed BigInt.
1508 =head2 denominator()
1510 $d = $x->denominator();
1512 Returns a copy of the denominator (the part under the line) as positive BigInt.
1516 ($n,$d) = $x->parts();
1518 Return a list consisting of (signed) numerator and (unsigned) denominator as
1523 my $y = $x->numify();
1525 Returns the object as a scalar. This will lose some data if the object
1526 cannot be represented by a normal Perl scalar (integer or float), so
1527 use as_int() instead.
1529 This routine is automatically used whenever a scalar is required:
1531 my $x = Math::BigRat->new('3/1');
1533 $y = $array[$x]; # set $y to 3
1535 =head2 as_int()/as_number()
1537 $x = Math::BigRat->new('13/7');
1538 print $x->as_int(),"\n"; # '1'
1540 Returns a copy of the object as BigInt, truncated to an integer.
1542 C<as_number()> is an alias for C<as_int()>.
1546 $x = Math::BigRat->new('13');
1547 print $x->as_hex(),"\n"; # '0xd'
1549 Returns the BigRat as hexadecimal string. Works only for integers.
1553 $x = Math::BigRat->new('13');
1554 print $x->as_bin(),"\n"; # '0x1101'
1556 Returns the BigRat as binary string. Works only for integers.
1560 $x = Math::BigRat->new('13');
1561 print $x->as_oct(),"\n"; # '015'
1563 Returns the BigRat as octal string. Works only for integers.
1565 =head2 from_hex()/from_bin()/from_oct()
1567 my $h = Math::BigRat->from_hex('0x10');
1568 my $b = Math::BigRat->from_bin('0b10000000');
1569 my $o = Math::BigRat->from_oct('020');
1571 Create a BigRat from an hexadecimal, binary or octal number
1576 $len = $x->length();
1578 Return the length of $x in digitis for integer values.
1582 print Math::BigRat->new('123/1')->digit(1); # 1
1583 print Math::BigRat->new('123/1')->digit(-1); # 3
1585 Return the N'ths digit from X when X is an integer value.
1591 Reduce the number to the shortest form. This routine is called
1592 automatically whenever it is needed.
1598 Calculates the factorial of $x. For instance:
1600 print Math::BigRat->new('3/1')->bfac(),"\n"; # 1*2*3
1601 print Math::BigRat->new('5/1')->bfac(),"\n"; # 1*2*3*4*5
1603 Works currently only for integers.
1607 Is not yet implemented.
1609 =head2 bround()/round()/bfround()
1611 Are not yet implemented.
1616 my $x = Math::BigRat->new('7/4');
1617 my $y = Math::BigRat->new('4/3');
1620 Set $x to the remainder of the division of $x by $y.
1626 Used to negate the object in-place.
1630 print "$x is 1\n" if $x->is_one();
1632 Return true if $x is exactly one, otherwise false.
1636 print "$x is 0\n" if $x->is_zero();
1638 Return true if $x is exactly zero, otherwise false.
1640 =head2 is_pos()/is_positive()
1642 print "$x is >= 0\n" if $x->is_positive();
1644 Return true if $x is positive (greater than or equal to zero), otherwise
1645 false. Please note that '+inf' is also positive, while 'NaN' and '-inf' aren't.
1647 C<is_positive()> is an alias for C<is_pos()>.
1649 =head2 is_neg()/is_negative()
1651 print "$x is < 0\n" if $x->is_negative();
1653 Return true if $x is negative (smaller than zero), otherwise false. Please
1654 note that '-inf' is also negative, while 'NaN' and '+inf' aren't.
1656 C<is_negative()> is an alias for C<is_neg()>.
1660 print "$x is an integer\n" if $x->is_int();
1662 Return true if $x has a denominator of 1 (e.g. no fraction parts), otherwise
1663 false. Please note that '-inf', 'inf' and 'NaN' aren't integer.
1667 print "$x is odd\n" if $x->is_odd();
1669 Return true if $x is odd, otherwise false.
1673 print "$x is even\n" if $x->is_even();
1675 Return true if $x is even, otherwise false.
1681 Set $x to the next bigger integer value (e.g. truncate the number to integer
1682 and then increment it by one).
1688 Truncate $x to an integer value.
1694 Calculate the square root of $x.
1700 Calculate the N'th root of $x.
1702 =head2 badd()/bmul()/bsub()/bdiv()/bdec()/binc()
1704 Please see the documentation in L<Math::BigInt>.
1710 Makes a deep copy of the object.
1712 Please see the documentation in L<Math::BigInt> for further details.
1714 =head2 bstr()/bsstr()
1716 my $x = Math::BigInt->new('8/4');
1717 print $x->bstr(),"\n"; # prints 1/2
1718 print $x->bsstr(),"\n"; # prints 1/2
1720 Return a string representating this object.
1722 =head2 bacmp()/bcmp()
1724 Used to compare numbers.
1726 Please see the documentation in L<Math::BigInt> for further details.
1728 =head2 blsft()/brsft()
1730 Used to shift numbers left/right.
1732 Please see the documentation in L<Math::BigInt> for further details.
1740 Please see the documentation in L<Math::BigInt> for further details.
1746 print Dumper ( Math::BigRat->config() );
1747 print Math::BigRat->config()->{lib},"\n";
1749 Returns a hash containing the configuration, e.g. the version number, lib
1750 loaded etc. The following hash keys are currently filled in with the
1751 appropriate information.
1753 key RO/RW Description
1755 ============================================================
1756 lib RO Name of the Math library
1758 lib_version RO Version of 'lib'
1760 class RO The class of config you just called
1762 version RO version number of the class you used
1764 upgrade RW To which class numbers are upgraded
1766 downgrade RW To which class numbers are downgraded
1768 precision RW Global precision
1770 accuracy RW Global accuracy
1772 round_mode RW Global round mode
1774 div_scale RW Fallback accuracy for div
1776 trap_nan RW Trap creation of NaN (undef = no)
1778 trap_inf RW Trap creation of +inf/-inf (undef = no)
1781 By passing a reference to a hash you may set the configuration values. This
1782 works only for values that a marked with a C<RW> above, anything else is
1787 Some things are not yet implemented, or only implemented half-way:
1791 =item inf handling (partial)
1793 =item NaN handling (partial)
1795 =item rounding (not implemented except for bceil/bfloor)
1797 =item $x ** $y where $y is not an integer
1799 =item bmod(), blog(), bmodinv() and bmodpow() (partial)
1805 This program is free software; you may redistribute it and/or modify it under
1806 the same terms as Perl itself.
1810 L<Math::BigFloat> and L<Math::Big> as well as L<Math::BigInt::BitVect>,
1811 L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
1813 See L<http://search.cpan.org/search?dist=bignum> for a way to use
1816 The package at L<http://search.cpan.org/search?dist=Math%3A%3ABigRat>
1817 may contain more documentation and examples as well as testcases.
1821 (C) by Tels L<http://bloodgate.com/> 2001 - 2007.