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 if (@_ == 1 && ref($_[0]) ne 'HASH')
343 my $cfg = $class->SUPER::config();
344 return $cfg->{$_[0]};
347 my $cfg = $class->SUPER::config(@_);
349 # now we need only to override the ones that are different from our parent
350 $cfg->{class} = $class;
355 ##############################################################################
359 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
361 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
363 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
367 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # '+3/2' => '3/2'
369 return $s . $MBI->_str($x->{_n}) if $MBI->_is_one($x->{_d});
370 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
375 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
377 if ($x->{sign} !~ /^[+-]$/) # inf, NaN etc
379 my $s = $x->{sign}; $s =~ s/^\+//; # +inf => inf
383 my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3
384 $s . $MBI->_str($x->{_n}) . '/' . $MBI->_str($x->{_d});
389 # reduce the number to the shortest form
390 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
392 # Both parts must be objects of whatever we are using today.
393 if ( my $c = $MBI->_check($x->{_n}) )
395 require Carp; Carp::croak ("n did not pass the self-check ($c) in bnorm()");
397 if ( my $c = $MBI->_check($x->{_d}) )
399 require Carp; Carp::croak ("d did not pass the self-check ($c) in bnorm()");
402 # no normalize for NaN, inf etc.
403 return $x if $x->{sign} !~ /^[+-]$/;
405 # normalize zeros to 0/1
406 if ($MBI->_is_zero($x->{_n}))
408 $x->{sign} = '+'; # never leave a -0
409 $x->{_d} = $MBI->_one() unless $MBI->_is_one($x->{_d});
413 return $x if $MBI->_is_one($x->{_d}); # no need to reduce
415 # reduce other numbers
416 my $gcd = $MBI->_copy($x->{_n});
417 $gcd = $MBI->_gcd($gcd,$x->{_d});
419 if (!$MBI->_is_one($gcd))
421 $x->{_n} = $MBI->_div($x->{_n},$gcd);
422 $x->{_d} = $MBI->_div($x->{_d},$gcd);
427 ##############################################################################
432 # (BRAT or num_str) return BRAT
433 # negate number or make a negated number from string
434 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
436 return $x if $x->modify('bneg');
438 # for +0 dont negate (to have always normalized +0). Does nothing for 'NaN'
439 $x->{sign} =~ tr/+-/-+/ unless ($x->{sign} eq '+' && $MBI->_is_zero($x->{_n}));
443 ##############################################################################
448 # used by parent class bnan() to initialize number to NaN
454 my $class = ref($self);
455 # "$self" below will stringify the object, this blows up if $self is a
456 # partial object (happens under trap_nan), so fix it beforehand
457 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
458 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
459 Carp::croak ("Tried to set $self to NaN in $class\::_bnan()");
461 $self->{_n} = $MBI->_zero();
462 $self->{_d} = $MBI->_zero();
467 # used by parent class bone() to initialize number to +inf/-inf
473 my $class = ref($self);
474 # "$self" below will stringify the object, this blows up if $self is a
475 # partial object (happens under trap_nan), so fix it beforehand
476 $self->{_d} = $MBI->_zero() unless defined $self->{_d};
477 $self->{_n} = $MBI->_zero() unless defined $self->{_n};
478 Carp::croak ("Tried to set $self to inf in $class\::_binf()");
480 $self->{_n} = $MBI->_zero();
481 $self->{_d} = $MBI->_zero();
486 # used by parent class bone() to initialize number to +1/-1
488 $self->{_n} = $MBI->_one();
489 $self->{_d} = $MBI->_one();
494 # used by parent class bzero() to initialize number to 0
496 $self->{_n} = $MBI->_zero();
497 $self->{_d} = $MBI->_one();
500 ##############################################################################
505 # add two rational numbers
508 my ($self,$x,$y,@r) = (ref($_[0]),@_);
509 # objectify is costly, so avoid it
510 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
512 ($self,$x,$y,@r) = objectify(2,@_);
515 # +inf + +inf => +inf, -inf + -inf => -inf
516 return $x->binf(substr($x->{sign},0,1))
517 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
519 # +inf + -inf or -inf + +inf => NaN
520 return $x->bnan() if ($x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/);
522 # 1 1 gcd(3,4) = 1 1*3 + 1*4 7
523 # - + - = --------- = --
526 # we do not compute the gcd() here, but simple do:
528 # - + - = --------- = --
531 # and bnorm() will then take care of the rest
534 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
537 my $m = $MBI->_mul( $MBI->_copy( $y->{_n} ), $x->{_d} );
540 ($x->{_n}, $x->{sign}) = _e_add( $x->{_n}, $m, $x->{sign}, $y->{sign});
543 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
545 # normalize result, and possible round
546 $x->bnorm()->round(@r);
551 # subtract two rational numbers
554 my ($self,$x,$y,@r) = (ref($_[0]),@_);
555 # objectify is costly, so avoid it
556 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
558 ($self,$x,$y,@r) = objectify(2,@_);
561 # flip sign of $x, call badd(), then flip sign of result
562 $x->{sign} =~ tr/+-/-+/
563 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
564 $x->badd($y,@r); # does norm and round
565 $x->{sign} =~ tr/+-/-+/
566 unless $x->{sign} eq '+' && $MBI->_is_zero($x->{_n}); # not -0
572 # multiply two rational numbers
575 my ($self,$x,$y,@r) = (ref($_[0]),@_);
576 # objectify is costly, so avoid it
577 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
579 ($self,$x,$y,@r) = objectify(2,@_);
582 return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN');
585 if (($x->{sign} =~ /^[+-]inf$/) || ($y->{sign} =~ /^[+-]inf$/))
587 return $x->bnan() if $x->is_zero() || $y->is_zero();
588 # result will always be +-inf:
589 # +inf * +/+inf => +inf, -inf * -/-inf => +inf
590 # +inf * -/-inf => -inf, -inf * +/+inf => -inf
591 return $x->binf() if ($x->{sign} =~ /^\+/ && $y->{sign} =~ /^\+/);
592 return $x->binf() if ($x->{sign} =~ /^-/ && $y->{sign} =~ /^-/);
593 return $x->binf('-');
596 # x== 0 # also: or y == 1 or y == -1
597 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
600 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
601 # and reducing in one step. This would save us the bnorm() at the end.
604 # - * - = ----- = - = -
607 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_n});
608 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_d});
611 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
613 $x->bnorm()->round(@r);
618 # (dividend: BRAT or num_str, divisor: BRAT or num_str) return
619 # (BRAT,BRAT) (quo,rem) or BRAT (only rem)
622 my ($self,$x,$y,@r) = (ref($_[0]),@_);
623 # objectify is costly, so avoid it
624 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
626 ($self,$x,$y,@r) = objectify(2,@_);
629 return $self->_div_inf($x,$y)
630 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
632 # x== 0 # also: or y == 1 or y == -1
633 return wantarray ? ($x,$self->bzero()) : $x if $x->is_zero();
635 # XXX TODO: list context, upgrade
636 # According to Knuth, this can be optimized by doing gcd twice (for d and n)
637 # and reducing in one step. This would save us the bnorm() at the end.
643 $x->{_n} = $MBI->_mul( $x->{_n}, $y->{_d});
644 $x->{_d} = $MBI->_mul( $x->{_d}, $y->{_n});
647 $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-';
649 $x->bnorm()->round(@r);
655 # compute "remainder" (in Perl way) of $x / $y
658 my ($self,$x,$y,@r) = (ref($_[0]),@_);
659 # objectify is costly, so avoid it
660 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
662 ($self,$x,$y,@r) = objectify(2,@_);
665 return $self->_div_inf($x,$y)
666 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero());
668 return $x if $x->is_zero(); # 0 / 7 = 0, mod 0
670 # compute $x - $y * floor($x/$y), keeping the sign of $x
672 # copy x to u, make it positive and then do a normal division ($u/$y)
673 my $u = bless { sign => '+' }, $self;
674 $u->{_n} = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d} );
675 $u->{_d} = $MBI->_mul( $MBI->_copy($x->{_d}), $y->{_n} );
678 if (! $MBI->_is_one($u->{_d}))
680 $u->{_n} = $MBI->_div($u->{_n},$u->{_d}); # 22/7 => 3/1 w/ truncate
681 # no need to set $u->{_d} to 1, since below we set it to $y->{_d} anyway
684 # now compute $y * $u
685 $u->{_d} = $MBI->_copy($y->{_d}); # 1 * $y->{_d}, see floor above
686 $u->{_n} = $MBI->_mul($u->{_n},$y->{_n});
688 my $xsign = $x->{sign}; $x->{sign} = '+'; # remember sign and make x positive
691 $x->{sign} = $xsign; # put sign back
693 $x->bnorm()->round(@r);
696 ##############################################################################
701 # decrement value (subtract 1)
702 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
704 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
706 if ($x->{sign} eq '-')
708 $x->{_n} = $MBI->_add( $x->{_n}, $x->{_d}); # -5/2 => -7/2
712 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0) # n < d?
715 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
720 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # 5/2 => 3/2
723 $x->bnorm()->round(@r);
728 # increment value (add 1)
729 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
731 return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf
733 if ($x->{sign} eq '-')
735 if ($MBI->_acmp($x->{_n},$x->{_d}) < 0)
737 # -1/3 ++ => 2/3 (overflow at 0)
738 $x->{_n} = $MBI->_sub( $MBI->_copy($x->{_d}), $x->{_n});
743 $x->{_n} = $MBI->_sub($x->{_n}, $x->{_d}); # -5/2 => -3/2
748 $x->{_n} = $MBI->_add($x->{_n},$x->{_d}); # 5/2 => 7/2
750 $x->bnorm()->round(@r);
753 ##############################################################################
754 # is_foo methods (the rest is inherited)
758 # return true if arg (BRAT or num_str) is an integer
759 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
761 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN and +-inf aren't
762 $MBI->_is_one($x->{_d}); # x/y && y != 1 => no integer
768 # return true if arg (BRAT or num_str) is zero
769 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
771 return 1 if $x->{sign} eq '+' && $MBI->_is_zero($x->{_n});
777 # return true if arg (BRAT or num_str) is +1 or -1 if signis given
778 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
780 my $sign = $_[2] || ''; $sign = '+' if $sign ne '-';
782 if ($x->{sign} eq $sign && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}));
788 # return true if arg (BFLOAT or num_str) is odd or false if even
789 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
791 return 1 if ($x->{sign} =~ /^[+-]$/) && # NaN & +-inf aren't
792 ($MBI->_is_one($x->{_d}) && $MBI->_is_odd($x->{_n})); # x/2 is not, but 3/1
798 # return true if arg (BINT or num_str) is even or false if odd
799 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
801 return 0 if $x->{sign} !~ /^[+-]$/; # NaN & +-inf aren't
802 return 1 if ($MBI->_is_one($x->{_d}) # x/3 is never
803 && $MBI->_is_even($x->{_n})); # but 4/1 is
807 ##############################################################################
808 # parts() and friends
812 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
815 return Math::BigInt->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/);
817 my $n = Math::BigInt->new($MBI->_str($x->{_n})); $n->{sign} = $x->{sign};
823 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
826 return Math::BigInt->new($x->{sign}) if $x->{sign} eq 'NaN';
828 return Math::BigInt->bone() if $x->{sign} !~ /^[+-]$/;
830 Math::BigInt->new($MBI->_str($x->{_d}));
835 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
837 my $c = 'Math::BigInt';
839 return ($c->bnan(),$c->bnan()) if $x->{sign} eq 'NaN';
840 return ($c->binf(),$c->binf()) if $x->{sign} eq '+inf';
841 return ($c->binf('-'),$c->binf()) if $x->{sign} eq '-inf';
843 my $n = $c->new( $MBI->_str($x->{_n}));
844 $n->{sign} = $x->{sign};
845 my $d = $c->new( $MBI->_str($x->{_d}));
851 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
853 return $nan unless $x->is_int();
854 $MBI->_len($x->{_n}); # length(-123/1) => length(123)
859 my ($self,$x,$n) = ref($_[0]) ? (undef,$_[0],$_[1]) : objectify(1,@_);
861 return $nan unless $x->is_int();
862 $MBI->_digit($x->{_n},$n || 0); # digit(-123/1,2) => digit(123,2)
865 ##############################################################################
866 # special calc routines
870 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
872 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
873 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
875 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
876 $x->{_d} = $MBI->_one(); # d => 1
877 $x->{_n} = $MBI->_inc($x->{_n})
878 if $x->{sign} eq '+'; # +22/7 => 4/1
879 $x->{sign} = '+' if $MBI->_is_zero($x->{_n}); # -0 => 0
885 my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_);
887 return $x if $x->{sign} !~ /^[+-]$/ || # not for NaN, inf
888 $MBI->_is_one($x->{_d}); # 22/1 => 22, 0/1 => 0
890 $x->{_n} = $MBI->_div($x->{_n},$x->{_d}); # 22/7 => 3/1 w/ truncate
891 $x->{_d} = $MBI->_one(); # d => 1
892 $x->{_n} = $MBI->_inc($x->{_n})
893 if $x->{sign} eq '-'; # -22/7 => -4/1
899 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
901 # if $x is not an integer
902 if (($x->{sign} ne '+') || (!$MBI->_is_one($x->{_d})))
907 $x->{_n} = $MBI->_fac($x->{_n});
908 # since _d is 1, we don't need to reduce/norm the result
917 my ($self,$x,$y,@r) = (ref($_[0]),@_);
918 # objectify is costly, so avoid it
919 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
921 ($self,$x,$y,@r) = objectify(2,@_);
924 return $x if $x->{sign} =~ /^[+-]inf$/; # -inf/+inf ** x
925 return $x->bnan() if $x->{sign} eq $nan || $y->{sign} eq $nan;
926 return $x->bone(@r) if $y->is_zero();
927 return $x->round(@r) if $x->is_one() || $y->is_one();
929 if ($x->{sign} eq '-' && $MBI->_is_one($x->{_n}) && $MBI->_is_one($x->{_d}))
931 # if $x == -1 and odd/even y => +1/-1
932 return $y->is_odd() ? $x->round(@r) : $x->babs()->round(@r);
933 # my Casio FX-5500L has a bug here: -1 ** 2 is -1, but -1 * -1 is 1;
935 # 1 ** -y => 1 / (1 ** |y|)
936 # so do test for negative $y after above's clause
938 return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0)
940 # shortcut y/1 (and/or x/1)
941 if ($MBI->_is_one($y->{_d}))
943 # shortcut for x/1 and y/1
944 if ($MBI->_is_one($x->{_d}))
946 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # x/1 ** y/1 => (x ** y)/1
947 if ($y->{sign} eq '-')
949 # 0.2 ** -3 => 1/(0.2 ** 3)
950 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
952 # correct sign; + ** + => +
953 if ($x->{sign} eq '-')
955 # - * - => +, - * - * - => -
956 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
958 return $x->round(@r);
961 $x->{_n} = $MBI->_pow($x->{_n},$y->{_n}); # 5/2 ** y/1 => 5 ** y / 2 ** y
962 $x->{_d} = $MBI->_pow($x->{_d},$y->{_n});
963 if ($y->{sign} eq '-')
965 # 0.2 ** -3 => 1/(0.2 ** 3)
966 ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap
968 # correct sign; + ** + => +
969 if ($x->{sign} eq '-')
971 # - * - => +, - * - * - => -
972 $x->{sign} = '+' if $MBI->_is_even($y->{_n});
974 return $x->round(@r);
977 # regular calculation (this is wrong for d/e ** f/g)
978 my $pow2 = $self->bone();
979 my $y1 = $MBI->_div ( $MBI->_copy($y->{_n}), $y->{_d});
980 my $two = $MBI->_two();
982 while (!$MBI->_is_one($y1))
984 $pow2->bmul($x) if $MBI->_is_odd($y1);
985 $MBI->_div($y1, $two);
988 $x->bmul($pow2) unless $pow2->is_one();
989 # n ** -x => 1/n ** x
990 ($x->{_d},$x->{_n}) = ($x->{_n},$x->{_d}) if $y->{sign} eq '-';
991 $x->bnorm()->round(@r);
997 my ($self,$x,$y,@r) = (ref($_[0]),@_);
999 # objectify is costly, so avoid it
1000 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1002 ($self,$x,$y,@r) = objectify(2,$class,@_);
1006 return $x->bzero() if $x->is_one() && $y->{sign} eq '+';
1009 return $x->bnan() if $x->is_zero() || $x->{sign} ne '+' || $y->{sign} ne '+';
1011 if ($x->is_int() && $y->is_int())
1013 return $self->new($x->as_number()->blog($y->as_number(),@r));
1017 $x->_new_from_float( $x->_as_float()->blog(Math::BigFloat->new("$y"),@r) );
1023 my ($self,$x,$y,$a,$p,$r) = (ref($_[0]),@_);
1025 # objectify is costly, so avoid it
1026 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1028 ($self,$x,$y,$a,$p,$r) = objectify(2,$class,@_);
1031 return $x->binf() if $x->{sign} eq '+inf';
1032 return $x->bzero() if $x->{sign} eq '-inf';
1034 # we need to limit the accuracy to protect against overflow
1036 my ($scale,@params);
1037 ($x,@params) = $x->_find_round_parameters($a,$p,$r);
1039 # also takes care of the "error in _find_round_parameters?" case
1040 return $x if $x->{sign} eq 'NaN';
1042 # no rounding at all, so must use fallback
1043 if (scalar @params == 0)
1045 # simulate old behaviour
1046 $params[0] = $self->div_scale(); # and round to it as accuracy
1047 $params[1] = undef; # P = undef
1048 $scale = $params[0]+4; # at least four more for proper round
1049 $params[2] = $r; # round mode by caller or undef
1050 $fallback = 1; # to clear a/p afterwards
1054 # the 4 below is empirical, and there might be cases where it's not enough...
1055 $scale = abs($params[0] || $params[1]) + 4; # take whatever is defined
1058 return $x->bone(@params) if $x->is_zero();
1060 # See the comments in Math::BigFloat on how this algorithm works.
1061 # Basically we calculate A and B (where B is faculty(N)) so that A/B = e
1063 my $x_org = $x->copy();
1066 # set $x directly from a cached string form
1067 $x->{_n} = $MBI->_new("90933395208605785401971970164779391644753259799242");
1068 $x->{_d} = $MBI->_new("33452526613163807108170062053440751665152000000000");
1073 # compute A and B so that e = A / B.
1075 # After some terms we end up with this, so we use it as a starting point:
1076 my $A = $MBI->_new("90933395208605785401971970164779391644753259799242");
1077 my $F = $MBI->_new(42); my $step = 42;
1079 # Compute how many steps we need to take to get $A and $B sufficiently big
1080 my $steps = Math::BigFloat::_len_to_steps($scale - 4);
1081 # print STDERR "# Doing $steps steps for ", $scale-4, " digits\n";
1082 while ($step++ <= $steps)
1084 # calculate $a * $f + 1
1085 $A = $MBI->_mul($A, $F);
1086 $A = $MBI->_inc($A);
1088 $F = $MBI->_inc($F);
1090 # compute $B as factorial of $steps (this is faster than doing it manually)
1091 my $B = $MBI->_fac($MBI->_new($steps));
1093 # print "A ", $MBI->_str($A), "\nB ", $MBI->_str($B), "\n";
1100 # $x contains now an estimate of e, with some surplus digits, so we can round
1101 if (!$x_org->is_one())
1103 # raise $x to the wanted power and round it in one step:
1104 $x->bpow($x_org, @params);
1108 # else just round the already computed result
1109 delete $x->{_a}; delete $x->{_p};
1110 # shortcut to not run through _find_round_parameters again
1111 if (defined $params[0])
1113 $x->bround($params[0],$params[2]); # then round accordingly
1117 $x->bfround($params[1],$params[2]); # then round accordingly
1122 # clear a/p after round, since user did not request it
1123 delete $x->{_a}; delete $x->{_p};
1132 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1134 # objectify is costly, so avoid it
1135 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1137 ($self,$x,$y,@r) = objectify(2,$class,@_);
1141 $x->_new_from_float( $x->_as_float()->bnok(Math::BigFloat->new("$y"),@r) );
1144 sub _float_from_part
1148 my $f = Math::BigFloat->bzero();
1149 $f->{_m} = $MBI->_copy($x);
1150 $f->{_e} = $MBI->_zero();
1159 local $Math::BigFloat::upgrade = undef;
1160 local $Math::BigFloat::accuracy = undef;
1161 local $Math::BigFloat::precision = undef;
1162 # 22/7 => 3.142857143..
1164 my $a = $x->accuracy() || 0;
1165 if ($a != 0 || !$MBI->_is_one($x->{_d}))
1168 return Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}))->bdiv( $MBI->_str($x->{_d}), $x->accuracy());
1171 Math::BigFloat->new($x->{sign} . $MBI->_str($x->{_n}));
1177 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1178 # objectify is costly, so avoid it
1179 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1181 ($self,$x,$y,@r) = objectify(2,@_);
1184 if ($x->is_int() && $y->is_int())
1186 return $self->new($x->as_number()->broot($y->as_number(),@r));
1190 $x->_new_from_float( $x->_as_float()->broot($y,@r) );
1196 my ($self,$x,$y,$m,@r) = (ref($_[0]),@_);
1197 # objectify is costly, so avoid it
1198 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1200 ($self,$x,$y,$m,@r) = objectify(3,@_);
1203 # $x or $y or $m are NaN or +-inf => NaN
1205 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/ ||
1206 $m->{sign} !~ /^[+-]$/;
1208 if ($x->is_int() && $y->is_int() && $m->is_int())
1210 return $self->new($x->as_number()->bmodpow($y->as_number(),$m,@r));
1213 warn ("bmodpow() not fully implemented");
1220 my ($self,$x,$y,@r) = (ref($_[0]),@_);
1221 # objectify is costly, so avoid it
1222 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1224 ($self,$x,$y,@r) = objectify(2,@_);
1227 # $x or $y are NaN or +-inf => NaN
1229 if $x->{sign} !~ /^[+-]$/ || $y->{sign} !~ /^[+-]$/;
1231 if ($x->is_int() && $y->is_int())
1233 return $self->new($x->as_number()->bmodinv($y->as_number(),@r));
1236 warn ("bmodinv() not fully implemented");
1242 my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_);
1244 return $x->bnan() if $x->{sign} !~ /^[+]/; # NaN, -inf or < 0
1245 return $x if $x->{sign} eq '+inf'; # sqrt(inf) == inf
1246 return $x->round(@r) if $x->is_zero() || $x->is_one();
1248 local $Math::BigFloat::upgrade = undef;
1249 local $Math::BigFloat::downgrade = undef;
1250 local $Math::BigFloat::precision = undef;
1251 local $Math::BigFloat::accuracy = undef;
1252 local $Math::BigInt::upgrade = undef;
1253 local $Math::BigInt::precision = undef;
1254 local $Math::BigInt::accuracy = undef;
1256 $x->{_n} = _float_from_part( $x->{_n} )->bsqrt();
1257 $x->{_d} = _float_from_part( $x->{_d} )->bsqrt();
1259 # XXX TODO: we probably can optimze this:
1261 # if sqrt(D) was not integer
1262 if ($x->{_d}->{_es} ne '+')
1264 $x->{_n}->blsft($x->{_d}->exponent()->babs(),10); # 7.1/4.51 => 7.1/45.1
1265 $x->{_d} = $MBI->_copy( $x->{_d}->{_m} ); # 7.1/45.1 => 71/45.1
1267 # if sqrt(N) was not integer
1268 if ($x->{_n}->{_es} ne '+')
1270 $x->{_d}->blsft($x->{_n}->exponent()->babs(),10); # 71/45.1 => 710/45.1
1271 $x->{_n} = $MBI->_copy( $x->{_n}->{_m} ); # 710/45.1 => 710/451
1274 # convert parts to $MBI again
1275 $x->{_n} = $MBI->_lsft( $MBI->_copy( $x->{_n}->{_m} ), $x->{_n}->{_e}, 10)
1276 if ref($x->{_n}) ne $MBI && ref($x->{_n}) ne 'ARRAY';
1277 $x->{_d} = $MBI->_lsft( $MBI->_copy( $x->{_d}->{_m} ), $x->{_d}->{_e}, 10)
1278 if ref($x->{_d}) ne $MBI && ref($x->{_d}) ne 'ARRAY';
1280 $x->bnorm()->round(@r);
1285 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1287 $b = 2 unless defined $b;
1288 $b = $self->new($b) unless ref ($b);
1289 $x->bmul( $b->copy()->bpow($y), @r);
1295 my ($self,$x,$y,$b,@r) = objectify(3,@_);
1297 $b = 2 unless defined $b;
1298 $b = $self->new($b) unless ref ($b);
1299 $x->bdiv( $b->copy()->bpow($y), @r);
1303 ##############################################################################
1321 ##############################################################################
1326 # compare two signed numbers
1329 my ($self,$x,$y) = (ref($_[0]),@_);
1330 # objectify is costly, so avoid it
1331 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1333 ($self,$x,$y) = objectify(2,@_);
1336 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1338 # handle +-inf and NaN
1339 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1340 return 0 if $x->{sign} eq $y->{sign} && $x->{sign} =~ /^[+-]inf$/;
1341 return +1 if $x->{sign} eq '+inf';
1342 return -1 if $x->{sign} eq '-inf';
1343 return -1 if $y->{sign} eq '+inf';
1346 # check sign for speed first
1347 return 1 if $x->{sign} eq '+' && $y->{sign} eq '-'; # does also 0 <=> -y
1348 return -1 if $x->{sign} eq '-' && $y->{sign} eq '+'; # does also -x <=> 0
1351 my $xz = $MBI->_is_zero($x->{_n});
1352 my $yz = $MBI->_is_zero($y->{_n});
1353 return 0 if $xz && $yz; # 0 <=> 0
1354 return -1 if $xz && $y->{sign} eq '+'; # 0 <=> +y
1355 return 1 if $yz && $x->{sign} eq '+'; # +x <=> 0
1357 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1358 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1360 my $cmp = $MBI->_acmp($t,$u); # signs are equal
1361 $cmp = -$cmp if $x->{sign} eq '-'; # both are '-' => reverse
1367 # compare two numbers (as unsigned)
1370 my ($self,$x,$y) = (ref($_[0]),@_);
1371 # objectify is costly, so avoid it
1372 if ((!ref($_[0])) || (ref($_[0]) ne ref($_[1])))
1374 ($self,$x,$y) = objectify(2,$class,@_);
1377 if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/))
1379 # handle +-inf and NaN
1380 return undef if (($x->{sign} eq $nan) || ($y->{sign} eq $nan));
1381 return 0 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} =~ /^[+-]inf$/;
1382 return 1 if $x->{sign} =~ /^[+-]inf$/ && $y->{sign} !~ /^[+-]inf$/;
1386 my $t = $MBI->_mul( $MBI->_copy($x->{_n}), $y->{_d});
1387 my $u = $MBI->_mul( $MBI->_copy($y->{_n}), $x->{_d});
1388 $MBI->_acmp($t,$u); # ignore signs
1391 ##############################################################################
1392 # output conversation
1396 # convert 17/8 => float (aka 2.125)
1397 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1399 return $x->bstr() if $x->{sign} !~ /^[+-]$/; # inf, NaN, etc
1402 my $neg = ''; $neg = '-' if $x->{sign} eq '-';
1403 return $neg . $MBI->_num($x->{_n}) if $MBI->_is_one($x->{_d});
1405 $x->_as_float()->numify() + 0.0;
1410 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1412 return Math::BigInt->new($x) if $x->{sign} !~ /^[+-]$/; # NaN, inf etc
1414 my $u = Math::BigInt->bzero();
1415 $u->{sign} = $x->{sign};
1416 $u->{value} = $MBI->_div( $MBI->_copy($x->{_n}), $x->{_d}); # 22/7 => 3
1422 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1424 return $x unless $x->is_int();
1426 my $s = $x->{sign}; $s = '' if $s eq '+';
1427 $s . $MBI->_as_bin($x->{_n});
1432 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1434 return $x unless $x->is_int();
1436 my $s = $x->{sign}; $s = '' if $s eq '+';
1437 $s . $MBI->_as_hex($x->{_n});
1442 my ($self,$x) = ref($_[0]) ? (undef,$_[0]) : objectify(1,@_);
1444 return $x unless $x->is_int();
1446 my $s = $x->{sign}; $s = '' if $s eq '+';
1447 $s . $MBI->_as_oct($x->{_n});
1450 ##############################################################################
1473 push @parts, Math::BigInt->from_oct($c);
1475 $class->new ( @parts );
1478 ##############################################################################
1485 my $lib = ''; my @a;
1488 for ( my $i = 0; $i < $l ; $i++)
1490 if ( $_[$i] eq ':constant' )
1492 # this rest causes overlord er load to step in
1493 overload::constant float => sub { $self->new(shift); };
1495 # elsif ($_[$i] eq 'upgrade')
1497 # # this causes upgrading
1498 # $upgrade = $_[$i+1]; # or undef to disable
1501 elsif ($_[$i] eq 'downgrade')
1503 # this causes downgrading
1504 $downgrade = $_[$i+1]; # or undef to disable
1507 elsif ($_[$i] =~ /^(lib|try|only)\z/)
1509 $lib = $_[$i+1] || ''; # default Calc
1510 $try = $1; # lib, try or only
1513 elsif ($_[$i] eq 'with')
1515 # this argument is no longer used
1516 #$MBI = $_[$i+1] || 'Math::BigInt::Calc'; # default Math::BigInt::Calc
1524 require Math::BigInt;
1526 # let use Math::BigInt lib => 'GMP'; use Math::BigRat; still have GMP
1529 my @c = split /\s*,\s*/, $lib;
1532 $_ =~ tr/a-zA-Z0-9://cd; # limit to sane characters
1534 $lib = join(",", @c);
1536 my @import = ('objectify');
1537 push @import, $try => $lib if $lib ne '';
1539 # MBI already loaded, so feed it our lib arguments
1540 Math::BigInt->import( @import );
1542 $MBI = Math::BigFloat->config()->{lib};
1544 # register us with MBI to get notified of future lib changes
1545 Math::BigInt::_register_callback( $self, sub { $MBI = $_[0]; } );
1547 # any non :constant stuff is handled by our parent, Exporter (loaded
1548 # by Math::BigFloat, even if @_ is empty, to give it a chance
1549 $self->SUPER::import(@a); # for subclasses
1550 $self->export_to_level(1,$self,@a); # need this, too
1559 Math::BigRat - Arbitrary big rational numbers
1565 my $x = Math::BigRat->new('3/7'); $x += '5/9';
1567 print $x->bstr(),"\n";
1570 my $y = Math::BigRat->new('inf');
1571 print "$y ", ($y->is_inf ? 'is' : 'is not') , " infinity\n";
1573 my $z = Math::BigRat->new(144); $z->bsqrt();
1577 Math::BigRat complements Math::BigInt and Math::BigFloat by providing support
1578 for arbitrary big rational numbers.
1582 You can change the underlying module that does the low-level
1583 math operations by using:
1585 use Math::BigRat try => 'GMP';
1587 Note: This needs Math::BigInt::GMP installed.
1589 The following would first try to find Math::BigInt::Foo, then
1590 Math::BigInt::Bar, and when this also fails, revert to Math::BigInt::Calc:
1592 use Math::BigRat try => 'Foo,Math::BigInt::Bar';
1594 If you want to get warned when the fallback occurs, replace "try" with
1597 use Math::BigRat lib => 'Foo,Math::BigInt::Bar';
1599 If you want the code to die instead, replace "try" with
1602 use Math::BigRat only => 'Foo,Math::BigInt::Bar';
1606 Any methods not listed here are derived from Math::BigFloat (or
1607 Math::BigInt), so make sure you check these two modules for further
1612 $x = Math::BigRat->new('1/3');
1614 Create a new Math::BigRat object. Input can come in various forms:
1616 $x = Math::BigRat->new(123); # scalars
1617 $x = Math::BigRat->new('inf'); # infinity
1618 $x = Math::BigRat->new('123.3'); # float
1619 $x = Math::BigRat->new('1/3'); # simple string
1620 $x = Math::BigRat->new('1 / 3'); # spaced
1621 $x = Math::BigRat->new('1 / 0.1'); # w/ floats
1622 $x = Math::BigRat->new(Math::BigInt->new(3)); # BigInt
1623 $x = Math::BigRat->new(Math::BigFloat->new('3.1')); # BigFloat
1624 $x = Math::BigRat->new(Math::BigInt::Lite->new('2')); # BigLite
1626 # You can also give D and N as different objects:
1627 $x = Math::BigRat->new(
1628 Math::BigInt->new(-123),
1629 Math::BigInt->new(7),
1634 $n = $x->numerator();
1636 Returns a copy of the numerator (the part above the line) as signed BigInt.
1638 =head2 denominator()
1640 $d = $x->denominator();
1642 Returns a copy of the denominator (the part under the line) as positive BigInt.
1646 ($n,$d) = $x->parts();
1648 Return a list consisting of (signed) numerator and (unsigned) denominator as
1653 my $y = $x->numify();
1655 Returns the object as a scalar. This will lose some data if the object
1656 cannot be represented by a normal Perl scalar (integer or float), so
1657 use as_int() instead.
1659 This routine is automatically used whenever a scalar is required:
1661 my $x = Math::BigRat->new('3/1');
1663 $y = $array[$x]; # set $y to 3
1665 =head2 as_int()/as_number()
1667 $x = Math::BigRat->new('13/7');
1668 print $x->as_int(),"\n"; # '1'
1670 Returns a copy of the object as BigInt, truncated to an integer.
1672 C<as_number()> is an alias for C<as_int()>.
1676 $x = Math::BigRat->new('13');
1677 print $x->as_hex(),"\n"; # '0xd'
1679 Returns the BigRat as hexadecimal string. Works only for integers.
1683 $x = Math::BigRat->new('13');
1684 print $x->as_bin(),"\n"; # '0x1101'
1686 Returns the BigRat as binary string. Works only for integers.
1690 $x = Math::BigRat->new('13');
1691 print $x->as_oct(),"\n"; # '015'
1693 Returns the BigRat as octal string. Works only for integers.
1695 =head2 from_hex()/from_bin()/from_oct()
1697 my $h = Math::BigRat->from_hex('0x10');
1698 my $b = Math::BigRat->from_bin('0b10000000');
1699 my $o = Math::BigRat->from_oct('020');
1701 Create a BigRat from an hexadecimal, binary or octal number
1706 $len = $x->length();
1708 Return the length of $x in digitis for integer values.
1712 print Math::BigRat->new('123/1')->digit(1); # 1
1713 print Math::BigRat->new('123/1')->digit(-1); # 3
1715 Return the N'ths digit from X when X is an integer value.
1721 Reduce the number to the shortest form. This routine is called
1722 automatically whenever it is needed.
1728 Calculates the factorial of $x. For instance:
1730 print Math::BigRat->new('3/1')->bfac(),"\n"; # 1*2*3
1731 print Math::BigRat->new('5/1')->bfac(),"\n"; # 1*2*3*4*5
1733 Works currently only for integers.
1735 =head2 bround()/round()/bfround()
1737 Are not yet implemented.
1742 my $x = Math::BigRat->new('7/4');
1743 my $y = Math::BigRat->new('4/3');
1746 Set $x to the remainder of the division of $x by $y.
1752 Used to negate the object in-place.
1756 print "$x is 1\n" if $x->is_one();
1758 Return true if $x is exactly one, otherwise false.
1762 print "$x is 0\n" if $x->is_zero();
1764 Return true if $x is exactly zero, otherwise false.
1766 =head2 is_pos()/is_positive()
1768 print "$x is >= 0\n" if $x->is_positive();
1770 Return true if $x is positive (greater than or equal to zero), otherwise
1771 false. Please note that '+inf' is also positive, while 'NaN' and '-inf' aren't.
1773 C<is_positive()> is an alias for C<is_pos()>.
1775 =head2 is_neg()/is_negative()
1777 print "$x is < 0\n" if $x->is_negative();
1779 Return true if $x is negative (smaller than zero), otherwise false. Please
1780 note that '-inf' is also negative, while 'NaN' and '+inf' aren't.
1782 C<is_negative()> is an alias for C<is_neg()>.
1786 print "$x is an integer\n" if $x->is_int();
1788 Return true if $x has a denominator of 1 (e.g. no fraction parts), otherwise
1789 false. Please note that '-inf', 'inf' and 'NaN' aren't integer.
1793 print "$x is odd\n" if $x->is_odd();
1795 Return true if $x is odd, otherwise false.
1799 print "$x is even\n" if $x->is_even();
1801 Return true if $x is even, otherwise false.
1807 Set $x to the next bigger integer value (e.g. truncate the number to integer
1808 and then increment it by one).
1814 Truncate $x to an integer value.
1820 Calculate the square root of $x.
1826 Calculate the N'th root of $x.
1828 =head2 badd()/bmul()/bsub()/bdiv()/bdec()/binc()
1830 Please see the documentation in L<Math::BigInt>.
1836 Makes a deep copy of the object.
1838 Please see the documentation in L<Math::BigInt> for further details.
1840 =head2 bstr()/bsstr()
1842 my $x = Math::BigInt->new('8/4');
1843 print $x->bstr(),"\n"; # prints 1/2
1844 print $x->bsstr(),"\n"; # prints 1/2
1846 Return a string representating this object.
1848 =head2 bacmp()/bcmp()
1850 Used to compare numbers.
1852 Please see the documentation in L<Math::BigInt> for further details.
1854 =head2 blsft()/brsft()
1856 Used to shift numbers left/right.
1858 Please see the documentation in L<Math::BigInt> for further details.
1866 Please see the documentation in L<Math::BigInt> for further details.
1870 $x->bexp($accuracy); # calculate e ** X
1872 Calculates two integers A and B so that A/B is equal to C<e ** $x>, where C<e> is
1875 This method was added in v0.20 of Math::BigRat (May 2007).
1881 $x->bnok($y); # x over y (binomial coefficient n over k)
1883 Calculates the binomial coefficient n over k, also called the "choose"
1884 function. The result is equivalent to:
1890 This method was added in v0.20 of Math::BigRat (May 2007).
1896 print Dumper ( Math::BigRat->config() );
1897 print Math::BigRat->config()->{lib},"\n";
1899 Returns a hash containing the configuration, e.g. the version number, lib
1900 loaded etc. The following hash keys are currently filled in with the
1901 appropriate information.
1903 key RO/RW Description
1905 ============================================================
1906 lib RO Name of the Math library
1908 lib_version RO Version of 'lib'
1910 class RO The class of config you just called
1912 version RO version number of the class you used
1914 upgrade RW To which class numbers are upgraded
1916 downgrade RW To which class numbers are downgraded
1918 precision RW Global precision
1920 accuracy RW Global accuracy
1922 round_mode RW Global round mode
1924 div_scale RW Fallback accuracy for div
1926 trap_nan RW Trap creation of NaN (undef = no)
1928 trap_inf RW Trap creation of +inf/-inf (undef = no)
1931 By passing a reference to a hash you may set the configuration values. This
1932 works only for values that a marked with a C<RW> above, anything else is
1937 Some things are not yet implemented, or only implemented half-way:
1941 =item inf handling (partial)
1943 =item NaN handling (partial)
1945 =item rounding (not implemented except for bceil/bfloor)
1947 =item $x ** $y where $y is not an integer
1949 =item bmod(), blog(), bmodinv() and bmodpow() (partial)
1955 This program is free software; you may redistribute it and/or modify it under
1956 the same terms as Perl itself.
1960 L<Math::BigFloat> and L<Math::Big> as well as L<Math::BigInt::BitVect>,
1961 L<Math::BigInt::Pari> and L<Math::BigInt::GMP>.
1963 See L<http://search.cpan.org/search?dist=bignum> for a way to use
1966 The package at L<http://search.cpan.org/search?dist=Math%3A%3ABigRat>
1967 may contain more documentation and examples as well as testcases.
1971 (C) by Tels L<http://bloodgate.com/> 2001 - 2007.