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 # XXX TODO: check that exponent() makes a copy to avoid copy()
213 my $diff_e = $nf->exponent()->copy()->bsub( $f->exponent);
214 if ($diff_e->is_negative())
217 $MBI->_lsft( $self->{_d}, $MBI->_new( $diff_e->babs()), 10);
219 elsif (!$diff_e->is_zero())
222 $MBI->_lsft( $self->{_n}, $MBI->_new( $diff_e), 10);
227 # both d and n look like (big)ints
229 $self->{sign} = '+'; # no sign => '+'
232 if ($n =~ /^([+-]?)0*([0-9]+)\z/) # first part ok?
234 $self->{sign} = $1 || '+'; # no sign => '+'
235 $self->{_n} = $MBI->_new($2 || 0);
238 if ($d =~ /^([+-]?)0*([0-9]+)\z/) # second part ok?
240 $self->{sign} =~ tr/+-/-+/ if ($1 || '') eq '-'; # negate if second part neg.
241 $self->{_d} = $MBI->_new($2 || 0);
244 if (!defined $self->{_n} || !defined $self->{_d})
246 $d = Math::BigInt->new($d,undef,undef) unless ref $d;
247 $n = Math::BigInt->new($n,undef,undef) unless ref $n;
249 if ($n->{sign} =~ /^[+-]$/ && $d->{sign} =~ /^[+-]$/)
251 # both parts are ok as integers (wierd things like ' 1e0'
252 $self->{_n} = $MBI->_copy($n->{value});
253 $self->{_d} = $MBI->_copy($d->{value});
254 $self->{sign} = $n->{sign};
255 $self->{sign} =~ tr/+-/-+/ if $d->{sign} eq '-'; # -1/-2 => 1/2
256 return $self->bnorm();
259 $self->{sign} = '+'; # a default sign
260 return $self->bnan() if $n->is_nan() || $d->is_nan();
263 if ($n->is_inf() || $d->is_inf())
267 return $self->bnan() if $d->is_inf(); # both are inf => NaN
268 my $s = '+'; # '+inf/+123' or '-inf/-123'
269 $s = '-' if substr($n->{sign},0,1) ne $d->{sign};
271 return $self->binf($s);
274 return $self->bzero();
279 return $self->bnorm();
282 # simple string input
283 if (($n =~ /[\.eE]/))
285 # looks like a float, quacks like a float, so probably is a float
286 $self->{sign} = 'NaN';
287 local $Math::BigFloat::accuracy = undef;
288 local $Math::BigFloat::precision = undef;
289 $self->_new_from_float(Math::BigFloat->new($n,undef,undef));
293 # for simple forms, use $MBI directly
294 if ($n =~ /^([+-]?)0*([0-9]+)\z/)
296 $self->{sign} = $1 || '+';
297 $self->{_n} = $MBI->_new($2 || 0);
298 $self->{_d} = $MBI->_one();
302 my $n = Math::BigInt->new($n,undef,undef);
303 $self->{_n} = $MBI->_copy($n->{value});
304 $self->{_d} = $MBI->_one();
305 $self->{sign} = $n->{sign};
306 return $self->bnan() if $self->{sign} eq 'NaN';
307 return $self->binf($self->{sign}) if $self->{sign} =~ /^[+-]inf$/;
315 # if two arguments, the first one is the class to "swallow" subclasses
323 return unless ref($x); # only for objects
325 my $self = bless {}, $c;
327 $self->{sign} = $x->{sign};
328 $self->{_d} = $MBI->_copy($x->{_d});
329 $self->{_n} = $MBI->_copy($x->{_n});
330 $self->{_a} = $x->{_a} if defined $x->{_a};
331 $self->{_p} = $x->{_p} if defined $x->{_p};
335 ##############################################################################
339 # return (later set?) configuration data as hash ref
340 my $class = shift || 'Math::BigRat';
342 my $cfg = $class->SUPER::config(@_);
344 # now we need only to override the ones that are different from our parent
345 $cfg->{class} = $class;
350 ##############################################################################
354 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
356 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
358 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
362 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # '+3/2' => '3/2'
364 return $s . $MBI->_str($x->{_n}) if $MBI->_is_one($x->{_d});
365 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
370 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
372 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
374 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
378 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3
379 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
384 # reduce the number to the shortest form
385 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
387 # Both parts must be objects of whatever we are using today.
388 # Second check because Calc.pm has ARRAY res as unblessed objects.
389 if (ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY')
391 require Carp; Carp::croak ("n is not $MBI but (".ref($x->{_n}).') in bnorm()');
393 if (ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY')
395 require Carp; Carp::croak ("d is not $MBI but (".ref($x->{_d}).') in bnorm()');
398 # no normalize for NaN, inf etc.
399 return $x if $x->{sign} !~ /^[+-]$/;
401 # normalize zeros to 0/1
402 if ($MBI->_is_zero($x->{_n}))
404 $x->{sign} = '+'; # never leave a -0
405 $x->{_d} = $MBI->_one() unless $MBI->_is_one($x->{_d});
409 return $x if $MBI->_is_one($x->{_d}); # no need to reduce
411 # reduce other numbers
412 my $gcd = $MBI->_copy($x->{_n});
413 $gcd = $MBI->_gcd($gcd,$x->{_d});
415 if (!$MBI->_is_one($gcd))
417 $x->{_n} = $MBI->_div($x->{_n},$gcd);
418 $x->{_d} = $MBI->_div($x->{_d},$gcd);
423 ##############################################################################
428 # (BRAT or num_str) return BRAT
429 # negate number or make a negated number from string
430 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
432 return $x if $x->modify('bneg');
434 # for +0 dont negate (to have always normalized +0). Does nothing for 'NaN'
435 $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $MBI->_is_zero($x->{_n}));
439 ##############################################################################
444 # used by parent class bnan() to initialize number to NaN
450 my $class = ref($self);
451 # "$self" below will stringify the object, this blows up if $self is a
452 # partial object (happens under trap_nan), so fix it beforehand
453 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
454 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
455 Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
457 $self->{_n} = $MBI->_zero();
458 $self->{_d} = $MBI->_zero();
463 # used by parent class bone() to initialize number to +inf/-inf
469 my $class = ref($self);
470 # "$self" below will stringify the object, this blows up if $self is a
471 # partial object (happens under trap_nan), so fix it beforehand
472 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
473 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
474 Carp::croak ("Tried to set $self to inf in $class\::_binf()");
476 $self->{_n} = $MBI->_zero();
477 $self->{_d} = $MBI->_zero();
482 # used by parent class bone() to initialize number to +1/-1
484 $self->{_n} = $MBI->_one();
485 $self->{_d} = $MBI->_one();
490 # used by parent class bzero() to initialize number to 0
492 $self->{_n} = $MBI->_zero();
493 $self->{_d} = $MBI->_one();
496 ##############################################################################
501 # add two rational numbers
504 my ($self,$x,$y,@r) = (ref($_[0]),@_);
505 # objectify is costly, so avoid it
506 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
508 ($self,$x,$y,@r) = objectify(2,@_);
511 # +inf + +inf => +inf, -inf + -inf => -inf
512 return $x->binf(substr($x->{sign},0,1))
513 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
515 # +inf + -inf or -inf + +inf => NaN
516 return $x->bnan() if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/);
518 # 1 1 gcd(3,4) = 1 1*3 + 1*4 7
519 # - + - = --------- = --
522 # we do not compute the gcd() here, but simple do:
524 # - + - = --------- = --
527 # and bnorm() will then take care of the rest
530 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
533 my $m = $MBI->_mul( $MBI->_copy( $y->{_n} ), $x->{_d} );
536 ($x->{_n}, $x->{sign}) = _e_add( $x->{_n}, $m, $x->{sign}, $y->{sign});
539 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
541 # normalize result, and possible round
542 $x->bnorm()->round(@r);
547 # subtract two rational numbers
550 my ($self,$x,$y,@r) = (ref($_[0]),@_);
551 # objectify is costly, so avoid it
552 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
554 ($self,$x,$y,@r) = objectify(2,@_);
557 # flip sign of $x, call badd(), then flip sign of result
558 $x->{sign} =~ tr/+-/-+/
559 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
560 $x->badd($y,@r); # does norm and round
561 $x->{sign} =~ tr/+-/-+/
562 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
568 # multiply two rational numbers
571 my ($self,$x,$y,@r) = (ref($_[0]),@_);
572 # objectify is costly, so avoid it
573 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
575 ($self,$x,$y,@r) = objectify(2,@_);
578 return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
581 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
583 return $x->bnan() if $x->is_zero() || $y->is_zero();
584 # result will always be +-inf:
585 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
586 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
587 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
588 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
589 return $x->binf('-');
592 # x== 0 # also: or y == 1 or y == -1
593 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
596 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
597 # and reducing in one step. This would save us the bnorm() at the end.
600 # - * - = ----- = - = -
603 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_n});
604 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
607 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
609 $x->bnorm()->round(@r);
614 # (dividend: BRAT or num_str, divisor: BRAT or num_str) return
615 # (BRAT,BRAT) (quo,rem) or BRAT (only rem)
618 my ($self,$x,$y,@r) = (ref($_[0]),@_);
619 # objectify is costly, so avoid it
620 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
622 ($self,$x,$y,@r) = objectify(2,@_);
625 return $self->_div_inf($x,$y)
626 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
628 # x== 0 # also: or y == 1 or y == -1
629 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
631 # XXX TODO: list context, upgrade
632 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
633 # and reducing in one step. This would save us the bnorm() at the end.
639 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
640 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_n});
643 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
645 $x->bnorm()->round(@r);
651 # compute "remainder" (in Perl way) of $x / $y
654 my ($self,$x,$y,@r) = (ref($_[0]),@_);
655 # objectify is costly, so avoid it
656 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
658 ($self,$x,$y,@r) = objectify(2,@_);
661 return $self->_div_inf($x,$y)
662 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
664 return $x if $x->is_zero(); # 0 / 7 = 0, mod 0
666 # compute $x - $y * floor($x/$y), keeping the sign of $x
668 # copy x to u, make it positive and then do a normal division ($u/$y)
669 my $u = bless { sign => '+' }, $self;
670 $u->{_n} = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d} );
671 $u->{_d} = $MBI->_mul( $MBI->_copy($x->{_d}), $y->{_n} );
674 if (! $MBI->_is_one($u->{_d}))
676 $u->{_n} = $MBI->_div($u->{_n},$u->{_d}); # 22/7 => 3/1 w/ truncate
677 # no need to set $u->{_d} to 1, since below we set it to $y->{_d} anyway
680 # now compute $y * $u
681 $u->{_d} = $MBI->_copy($y->{_d}); # 1 * $y->{_d}, see floor above
682 $u->{_n} = $MBI->_mul($u->{_n},$y->{_n});
684 my $xsign = $x->{sign}; $x->{sign} = '+'; # remember sign and make x positive
687 $x->{sign} = $xsign; # put sign back
689 $x->bnorm()->round(@r);
692 ##############################################################################
697 # decrement value (subtract 1)
698 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
700 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
702 if ($x->{sign} eq '-')
704 $x->{_n} = $MBI->_add( $x->{_n}, $x->{_d}); # -5/2 => -7/2
708 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0) # n < d?
711 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
716 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # 5/2 => 3/2
719 $x->bnorm()->round(@r);
724 # increment value (add 1)
725 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
727 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
729 if ($x->{sign} eq '-')
731 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0)
733 # -1/3 ++ => 2/3 (overflow at 0)
734 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
739 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # -5/2 => -3/2
744 $x->{_n} = $MBI->_add($x->{_n},$x->{_d}); # 5/2 => 7/2
746 $x->bnorm()->round(@r);
749 ##############################################################################
750 # is_foo methods (the rest is inherited)
754 # return true if arg (BRAT or num_str) is an integer
755 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
757 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
758 $MBI->_is_one($x->{_d}); # x/y && y != 1 => no integer
764 # return true if arg (BRAT or num_str) is zero
765 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
767 return 1 if $x->{sign} eq '+' && $MBI->_is_zero($x->{_n});
773 # return true if arg (BRAT or num_str) is +1 or -1 if signis given
774 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
776 my $sign = $_[2] || ''; $sign = '+' if $sign ne '-';
778 if ($x->{sign} eq $sign && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}));
784 # return true if arg (BFLOAT or num_str) is odd or false if even
785 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
787 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
788 ($MBI->_is_one($x->{_d}) && $MBI->_is_odd($x->{_n})); # x/2 is not, but 3/1
794 # return true if arg (BINT or num_str) is even or false if odd
795 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
797 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
798 return 1 if ($MBI->_is_one($x->{_d}) # x/3 is never
799 && $MBI->_is_even($x->{_n})); # but 4/1 is
803 ##############################################################################
804 # parts() and friends
808 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
811 return Math::BigInt->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/);
813 my $n = Math::BigInt->new($MBI->_str($x->{_n})); $n->{sign} = $x->{sign};
819 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
822 return Math::BigInt->new($x->{sign}) if $x->{sign} eq 'NaN';
824 return Math::BigInt->bone() if $x->{sign} !~ /^[+-]$/;
826 Math::BigInt->new($MBI->_str($x->{_d}));
831 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
833 my $c = 'Math::BigInt';
835 return ($c->bnan(),$c->bnan()) if $x->{sign} eq 'NaN';
836 return ($c->binf(),$c->binf()) if $x->{sign} eq '+inf';
837 return ($c->binf('-'),$c->binf()) if $x->{sign} eq '-inf';
839 my $n = $c->new( $MBI->_str($x->{_n}));
840 $n->{sign} = $x->{sign};
841 my $d = $c->new( $MBI->_str($x->{_d}));
847 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
849 return $nan unless $x->is_int();
850 $MBI->_len($x->{_n}); # length(-123/1) => length(123)
855 my ($self,$x,$n) = ref($_[0]) ? (undef,$_[0],$_[1]) : objectify(1,@_);
857 return $nan unless $x->is_int();
858 $MBI->_digit($x->{_n},$n || 0); # digit(-123/1,2) => digit(123,2)
861 ##############################################################################
862 # special calc routines
866 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
868 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
869 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
871 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
872 $x->{_d} = $MBI->_one(); # d => 1
873 $x->{_n} = $MBI->_inc($x->{_n})
874 if $x->{sign} eq '+'; # +22/7 => 4/1
875 $x->{sign} = '+' if $MBI->_is_zero($x->{_n}); # -0 => 0
881 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
883 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
884 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
886 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
887 $x->{_d} = $MBI->_one(); # d => 1
888 $x->{_n} = $MBI->_inc($x->{_n})
889 if $x->{sign} eq '-'; # -22/7 => -4/1
895 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
897 # if $x is not an integer
898 if (($x->{sign} ne '+') || (!$MBI->_is_one($x->{_d})))
903 $x->{_n} = $MBI->_fac($x->{_n});
904 # since _d is 1, we don't need to reduce/norm the result
913 my ($self,$x,$y,@r) = (ref($_[0]),@_);
914 # objectify is costly, so avoid it
915 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
917 ($self,$x,$y,@r) = objectify(2,@_);
920 return $x if $x->{sign} =~ /^[+-]inf$/; # -inf/+inf ** x
921 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
922 return $x->bone(@r) if $y->is_zero();
923 return $x->round(@r) if $x->is_one() || $y->is_one();
925 if ($x->{sign} eq '-' && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}))
927 # if $x == -1 and odd/even y => +1/-1
928 return $y->is_odd() ? $x->round(@r) : $x->babs()->round(@r);
929 # my Casio FX-5500L has a bug here: -1 ** 2 is -1, but -1 * -1 is 1;
931 # 1 ** -y => 1 / (1 ** |y|)
932 # so do test for negative $y after above's clause
934 return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0)
936 # shortcut y/1 (and/or x/1)
937 if ($MBI->_is_one($y->{_d}))
939 # shortcut for x/1 and y/1
940 if ($MBI->_is_one($x->{_d}))
942 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # x/1 ** y/1 => (x ** y)/1
943 if ($y->{sign} eq '-')
945 # 0.2 ** -3 => 1/(0.2 ** 3)
946 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
948 # correct sign; + ** + => +
949 if ($x->{sign} eq '-')
951 # - * - => +, - * - * - => -
952 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
954 return $x->round(@r);
957 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # 5/2 ** y/1 => 5 ** y / 2 ** y
958 $x->{_d} = $MBI->_pow($x->{_d},$y->{_n});
959 if ($y->{sign} eq '-')
961 # 0.2 ** -3 => 1/(0.2 ** 3)
962 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
964 # correct sign; + ** + => +
965 if ($x->{sign} eq '-')
967 # - * - => +, - * - * - => -
968 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
970 return $x->round(@r);
973 # regular calculation (this is wrong for d/e ** f/g)
974 my $pow2 = $self->bone();
975 my $y1 = $MBI->_div ( $MBI->_copy($y->{_n}), $y->{_d});
976 my $two = $MBI->_two();
978 while (!$MBI->_is_one($y1))
980 $pow2->bmul($x) if $MBI->_is_odd($y1);
981 $MBI->_div($y1, $two);
984 $x->bmul($pow2) unless $pow2->is_one();
985 # n ** -x => 1/n ** x
986 ($x->{_d},$x->{_n}) = ($x->{_n},$x->{_d}) if $y->{sign} eq '-';
987 $x->bnorm()->round(@r);
993 my ($self,$x,$y,@r) = (ref($_[0]),@_);
995 # objectify is costly, so avoid it
996 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
998 ($self,$x,$y,@r) = objectify(2,$class,@_);
1002 return $x->bzero() if $x->is_one() && $y->{sign} eq '+';
1005 return $x->bnan() if $x->is_zero() || $x->{sign} ne '+' || $y->{sign} ne '+';
1007 if ($x->is_int() && $y->is_int())
1009 return $self->new($x->as_number()->blog($y->as_number(),@r));
1013 $x->_new_from_float( $x->_as_float()->blog(Math::BigFloat->new("$y"),@r) );
1016 sub _float_from_part
1020 my $f = Math::BigFloat->bzero();
1021 $f->{_m} = $MBI->_copy($x);
1022 $f->{_e} = $MBI->_zero();
1031 local $Math::BigFloat::upgrade = undef;
1032 local $Math::BigFloat::accuracy = undef;
1033 local $Math::BigFloat::precision = undef;
1034 # 22/7 => 3.142857143..
1036 my $a = $x->accuracy() || 0;
1037 if ($a != 0 || !$MBI->_is_one($x->{_d}))
1040 return Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}))->bdiv( $MBI->_str($x->{_d}), $x->accuracy());
1043 Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}));
1049 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1050 # objectify is costly, so avoid it
1051 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1053 ($self,$x,$y,@r) = objectify(2,@_);
1056 if ($x->is_int() && $y->is_int())
1058 return $self->new($x->as_number()->broot($y->as_number(),@r));
1062 $x->_new_from_float( $x->_as_float()->broot($y,@r) );
1068 my ($self,$x,$y,$m,@r) = (ref($_[0]),@_);
1069 # objectify is costly, so avoid it
1070 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1072 ($self,$x,$y,$m,@r) = objectify(3,@_);
1075 # $x or $y or $m are NaN or +-inf => NaN
1077 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/ ||
1078 $m->{sign} !~ /^[+-]$/;
1080 if ($x->is_int() && $y->is_int() && $m->is_int())
1082 return $self->new($x->as_number()->bmodpow($y->as_number(),$m,@r));
1085 warn ("bmodpow() not fully implemented");
1092 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1093 # objectify is costly, so avoid it
1094 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1096 ($self,$x,$y,@r) = objectify(2,@_);
1099 # $x or $y are NaN or +-inf => NaN
1101 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
1103 if ($x->is_int() && $y->is_int())
1105 return $self->new($x->as_number()->bmodinv($y->as_number(),@r));
1108 warn ("bmodinv() not fully implemented");
1114 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1116 return $x->bnan() if $x->{sign} !~ /^[+]/; # NaN, -inf or < 0
1117 return $x if $x->{sign} eq '+inf'; # sqrt(inf) == inf
1118 return $x->round(@r) if $x->is_zero() || $x->is_one();
1120 local $Math::BigFloat::upgrade = undef;
1121 local $Math::BigFloat::downgrade = undef;
1122 local $Math::BigFloat::precision = undef;
1123 local $Math::BigFloat::accuracy = undef;
1124 local $Math::BigInt::upgrade = undef;
1125 local $Math::BigInt::precision = undef;
1126 local $Math::BigInt::accuracy = undef;
1128 $x->{_n} = _float_from_part( $x->{_n} )->bsqrt();
1129 $x->{_d} = _float_from_part( $x->{_d} )->bsqrt();
1131 # XXX TODO: we probably can optimze this:
1133 # if sqrt(D) was not integer
1134 if ($x->{_d}->{_es} ne '+')
1136 $x->{_n}->blsft($x->{_d}->exponent()->babs(),10); # 7.1/4.51 => 7.1/45.1
1137 $x->{_d} = $MBI->_copy( $x->{_d}->{_m} ); # 7.1/45.1 => 71/45.1
1139 # if sqrt(N) was not integer
1140 if ($x->{_n}->{_es} ne '+')
1142 $x->{_d}->blsft($x->{_n}->exponent()->babs(),10); # 71/45.1 => 710/45.1
1143 $x->{_n} = $MBI->_copy( $x->{_n}->{_m} ); # 710/45.1 => 710/451
1146 # convert parts to $MBI again
1147 $x->{_n} = $MBI->_lsft( $MBI->_copy( $x->{_n}->{_m} ), $x->{_n}->{_e}, 10)
1148 if ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY';
1149 $x->{_d} = $MBI->_lsft( $MBI->_copy( $x->{_d}->{_m} ), $x->{_d}->{_e}, 10)
1150 if ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY';
1152 $x->bnorm()->round(@r);
1157 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1159 $b = 2 unless defined $b;
1160 $b = $self->new($b) unless ref ($b);
1161 $x->bmul( $b->copy()->bpow($y), @r);
1167 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1169 $b = 2 unless defined $b;
1170 $b = $self->new($b) unless ref ($b);
1171 $x->bdiv( $b->copy()->bpow($y), @r);
1175 ##############################################################################
1193 ##############################################################################
1198 # compare two signed numbers
1201 my ($self,$x,$y) = (ref($_[0]),@_);
1202 # objectify is costly, so avoid it
1203 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1205 ($self,$x,$y) = objectify(2,@_);
1208 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1210 # handle +-inf and NaN
1211 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1212 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1213 return +1 if $x->{sign} eq '+inf';
1214 return -1 if $x->{sign} eq '-inf';
1215 return -1 if $y->{sign} eq '+inf';
1218 # check sign for speed first
1219 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1220 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1223 my $xz = $MBI->_is_zero($x->{_n});
1224 my $yz = $MBI->_is_zero($y->{_n});
1225 return 0 if $xz && $yz; # 0 <=> 0
1226 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
1227 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
1229 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1230 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1232 my $cmp = $MBI->_acmp($t,$u); # signs are equal
1233 $cmp = -$cmp if $x->{sign} eq '-'; # both are '-' => reverse
1239 # compare two numbers (as unsigned)
1242 my ($self,$x,$y) = (ref($_[0]),@_);
1243 # objectify is costly, so avoid it
1244 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1246 ($self,$x,$y) = objectify(2,$class,@_);
1249 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1251 # handle +-inf and NaN
1252 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1253 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
1254 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
1258 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1259 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1260 $MBI->_acmp($t,$u); # ignore signs
1263 ##############################################################################
1264 # output conversation
1268 # convert 17/8 => float (aka 2.125)
1269 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1271 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, NaN, etc
1274 my $neg = ''; $neg = '-' if $x->{sign} eq '-';
1275 return $neg . $MBI->_num($x->{_n}) if $MBI->_is_one($x->{_d});
1277 $x->_as_float()->numify() + 0.0;
1282 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1284 return Math::BigInt->new($x) if $x->{sign} !~ /^[+-]$/; # NaN, inf etc
1286 my $u = Math::BigInt->bzero();
1287 $u->{sign} = $x->{sign};
1288 $u->{value} = $MBI->_div( $MBI->_copy($x->{_n}), $x->{_d}); # 22/7 => 3
1294 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1296 return $x unless $x->is_int();
1298 my $s = $x->{sign}; $s = '' if $s eq '+';
1299 $s . $MBI->_as_bin($x->{_n});
1304 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1306 return $x unless $x->is_int();
1308 my $s = $x->{sign}; $s = '' if $s eq '+';
1309 $s . $MBI->_as_hex($x->{_n});
1314 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1316 return $x unless $x->is_int();
1318 my $s = $x->{sign}; $s = '' if $s eq '+';
1319 $s . $MBI->_as_oct($x->{_n});
1322 ##############################################################################
1345 push @parts, Math::BigInt->from_oct($c);
1347 $class->new ( @parts );
1350 ##############################################################################
1357 my $lib = ''; my @a;
1360 for ( my $i = 0; $i < $l ; $i++)
1362 if ( $_[$i] eq ':constant' )
1364 # this rest causes overlord er load to step in
1365 overload::constant float => sub { $self->new(shift); };
1367 # elsif ($_[$i] eq 'upgrade')
1369 # # this causes upgrading
1370 # $upgrade = $_[$i+1]; # or undef to disable
1373 elsif ($_[$i] eq 'downgrade')
1375 # this causes downgrading
1376 $downgrade = $_[$i+1]; # or undef to disable
1379 elsif ($_[$i] =~ /^(lib|try|only)\z/)
1381 $lib = $_[$i+1] || ''; # default Calc
1382 $try = $1; # lib, try or only
1385 elsif ($_[$i] eq 'with')
1387 # this argument is no longer used
1388 #$MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
1396 require Math::BigInt;
1398 # let use Math::BigInt lib => 'GMP'; use Math::BigRat; still have GMP
1401 my @c = split /\s*,\s*/, $lib;
1404 $_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
1406 $lib = join(",", @c);
1408 my @import = ('objectify');
1409 push @import, $try => $lib if $lib ne '';
1411 # MBI already loaded, so feed it our lib arguments
1412 Math::BigInt->import( @import );
1414 $MBI = Math::BigFloat->config()->{lib};
1416 # register us with MBI to get notified of future lib changes
1417 Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
1419 # any non :constant stuff is handled by our parent, Exporter (loaded
1420 # by Math::BigFloat, even if @_ is empty, to give it a chance
1421 $self->SUPER::import(@a); # for subclasses
1422 $self->export_to_level(1,$self,@a); # need this, too
1431 Math::BigRat - Arbitrary big rational numbers
1437 my $x = Math::BigRat->new('3/7'); $x += '5/9';
1439 print $x->bstr(),"\n";
1442 my $y = Math::BigRat->new('inf');
1443 print "$y ", ($y->is_inf ? 'is' : 'is not') , " infinity\n";
1445 my $z = Math::BigRat->new(144); $z->bsqrt();
1449 Math::BigRat complements Math::BigInt and Math::BigFloat by providing support
1450 for arbitrary big rational numbers.
1454 You can change the underlying module that does the low-level
1455 math operations by using:
1457 use Math::BigRat try => 'GMP';
1459 Note: This needs Math::BigInt::GMP installed.
1461 The following would first try to find Math::BigInt::Foo, then
1462 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
1464 use Math::BigRat try => 'Foo,Math::BigInt::Bar';
1466 If you want to get warned when the fallback occurs, replace "try" with
1469 use Math::BigRat lib => 'Foo,Math::BigInt::Bar';
1471 If you want the code to die instead, replace "try" with
1474 use Math::BigRat only => 'Foo,Math::BigInt::Bar';
1478 Any methods not listed here are derived from Math::BigFloat (or
1479 Math::BigInt), so make sure you check these two modules for further
1484 $x = Math::BigRat->new('1/3');
1486 Create a new Math::BigRat object. Input can come in various forms:
1488 $x = Math::BigRat->new(123); # scalars
1489 $x = Math::BigRat->new('inf'); # infinity
1490 $x = Math::BigRat->new('123.3'); # float
1491 $x = Math::BigRat->new('1/3'); # simple string
1492 $x = Math::BigRat->new('1 / 3'); # spaced
1493 $x = Math::BigRat->new('1 / 0.1'); # w/ floats
1494 $x = Math::BigRat->new(Math::BigInt->new(3)); # BigInt
1495 $x = Math::BigRat->new(Math::BigFloat->new('3.1')); # BigFloat
1496 $x = Math::BigRat->new(Math::BigInt::Lite->new('2')); # BigLite
1498 # You can also give D and N as different objects:
1499 $x = Math::BigRat->new(
1500 Math::BigInt->new(-123),
1501 Math::BigInt->new(7),
1506 $n = $x->numerator();
1508 Returns a copy of the numerator (the part above the line) as signed BigInt.
1510 =head2 denominator()
1512 $d = $x->denominator();
1514 Returns a copy of the denominator (the part under the line) as positive BigInt.
1518 ($n,$d) = $x->parts();
1520 Return a list consisting of (signed) numerator and (unsigned) denominator as
1525 my $y = $x->numify();
1527 Returns the object as a scalar. This will lose some data if the object
1528 cannot be represented by a normal Perl scalar (integer or float), so
1529 use as_int() instead.
1531 This routine is automatically used whenever a scalar is required:
1533 my $x = Math::BigRat->new('3/1');
1535 $y = $array[$x]; # set $y to 3
1537 =head2 as_int()/as_number()
1539 $x = Math::BigRat->new('13/7');
1540 print $x->as_int(),"\n"; # '1'
1542 Returns a copy of the object as BigInt, truncated to an integer.
1544 C<as_number()> is an alias for C<as_int()>.
1548 $x = Math::BigRat->new('13');
1549 print $x->as_hex(),"\n"; # '0xd'
1551 Returns the BigRat as hexadecimal string. Works only for integers.
1555 $x = Math::BigRat->new('13');
1556 print $x->as_bin(),"\n"; # '0x1101'
1558 Returns the BigRat as binary string. Works only for integers.
1562 $x = Math::BigRat->new('13');
1563 print $x->as_oct(),"\n"; # '015'
1565 Returns the BigRat as octal string. Works only for integers.
1567 =head2 from_hex()/from_bin()/from_oct()
1569 my $h = Math::BigRat->from_hex('0x10');
1570 my $b = Math::BigRat->from_bin('0b10000000');
1571 my $o = Math::BigRat->from_oct('020');
1573 Create a BigRat from an hexadecimal, binary or octal number
1578 $len = $x->length();
1580 Return the length of $x in digitis for integer values.
1584 print Math::BigRat->new('123/1')->digit(1); # 1
1585 print Math::BigRat->new('123/1')->digit(-1); # 3
1587 Return the N'ths digit from X when X is an integer value.
1593 Reduce the number to the shortest form. This routine is called
1594 automatically whenever it is needed.
1600 Calculates the factorial of $x. For instance:
1602 print Math::BigRat->new('3/1')->bfac(),"\n"; # 1*2*3
1603 print Math::BigRat->new('5/1')->bfac(),"\n"; # 1*2*3*4*5
1605 Works currently only for integers.
1609 Is not yet implemented.
1611 =head2 bround()/round()/bfround()
1613 Are not yet implemented.
1618 my $x = Math::BigRat->new('7/4');
1619 my $y = Math::BigRat->new('4/3');
1622 Set $x to the remainder of the division of $x by $y.
1628 Used to negate the object in-place.
1632 print "$x is 1\n" if $x->is_one();
1634 Return true if $x is exactly one, otherwise false.
1638 print "$x is 0\n" if $x->is_zero();
1640 Return true if $x is exactly zero, otherwise false.
1642 =head2 is_pos()/is_positive()
1644 print "$x is >= 0\n" if $x->is_positive();
1646 Return true if $x is positive (greater than or equal to zero), otherwise
1647 false. Please note that '+inf' is also positive, while 'NaN' and '-inf' aren't.
1649 C<is_positive()> is an alias for C<is_pos()>.
1651 =head2 is_neg()/is_negative()
1653 print "$x is < 0\n" if $x->is_negative();
1655 Return true if $x is negative (smaller than zero), otherwise false. Please
1656 note that '-inf' is also negative, while 'NaN' and '+inf' aren't.
1658 C<is_negative()> is an alias for C<is_neg()>.
1662 print "$x is an integer\n" if $x->is_int();
1664 Return true if $x has a denominator of 1 (e.g. no fraction parts), otherwise
1665 false. Please note that '-inf', 'inf' and 'NaN' aren't integer.
1669 print "$x is odd\n" if $x->is_odd();
1671 Return true if $x is odd, otherwise false.
1675 print "$x is even\n" if $x->is_even();
1677 Return true if $x is even, otherwise false.
1683 Set $x to the next bigger integer value (e.g. truncate the number to integer
1684 and then increment it by one).
1690 Truncate $x to an integer value.
1696 Calculate the square root of $x.
1702 Calculate the N'th root of $x.
1704 =head2 badd()/bmul()/bsub()/bdiv()/bdec()/binc()
1706 Please see the documentation in L<Math::BigInt>.
1712 Makes a deep copy of the object.
1714 Please see the documentation in L<Math::BigInt> for further details.
1716 =head2 bstr()/bsstr()
1718 my $x = Math::BigInt->new('8/4');
1719 print $x->bstr(),"\n"; # prints 1/2
1720 print $x->bsstr(),"\n"; # prints 1/2
1722 Return a string representating this object.
1724 =head2 bacmp()/bcmp()
1726 Used to compare numbers.
1728 Please see the documentation in L<Math::BigInt> for further details.
1730 =head2 blsft()/brsft()
1732 Used to shift numbers left/right.
1734 Please see the documentation in L<Math::BigInt> for further details.
1742 Please see the documentation in L<Math::BigInt> for further details.
1748 print Dumper ( Math::BigRat->config() );
1749 print Math::BigRat->config()->{lib},"\n";
1751 Returns a hash containing the configuration, e.g. the version number, lib
1752 loaded etc. The following hash keys are currently filled in with the
1753 appropriate information.
1755 key RO/RW Description
1757 ============================================================
1758 lib RO Name of the Math library
1760 lib_version RO Version of 'lib'
1762 class RO The class of config you just called
1764 version RO version number of the class you used
1766 upgrade RW To which class numbers are upgraded
1768 downgrade RW To which class numbers are downgraded
1770 precision RW Global precision
1772 accuracy RW Global accuracy
1774 round_mode RW Global round mode
1776 div_scale RW Fallback accuracy for div
1778 trap_nan RW Trap creation of NaN (undef = no)
1780 trap_inf RW Trap creation of +inf/-inf (undef = no)
1783 By passing a reference to a hash you may set the configuration values. This
1784 works only for values that a marked with a C<RW> above, anything else is
1789 Some things are not yet implemented, or only implemented half-way:
1793 =item inf handling (partial)
1795 =item NaN handling (partial)
1797 =item rounding (not implemented except for bceil/bfloor)
1799 =item $x ** $y where $y is not an integer
1801 =item bmod(), blog(), bmodinv() and bmodpow() (partial)
1807 This program is free software; you may redistribute it and/or modify it under
1808 the same terms as Perl itself.
1812 L<Math::BigFloat> and L<Math::Big> as well as L<Math::BigInt::BitVect>,
1813 L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
1815 See L<http://search.cpan.org/search?dist=bignum> for a way to use
1818 The package at L<http://search.cpan.org/search?dist=Math%3A%3ABigRat>
1819 may contain more documentation and examples as well as testcases.
1823 (C) by Tels L<http://bloodgate.com/> 2001 - 2007.