From: Jarkko Hietaniemi Date: Wed, 5 Jun 2002 00:27:47 +0000 (+0000) Subject: Upgrade to Math::BigRat 0.07. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a4e2b1c6aa0a5ea1df5718aa74e08e58648748a4;p=p5sagit%2Fp5-mst-13.2.git Upgrade to Math::BigRat 0.07. p4raw-id: //depot/perl@16994 --- diff --git a/lib/Math/BigRat.pm b/lib/Math/BigRat.pm index e08e661..41c4e10 100644 --- a/lib/Math/BigRat.pm +++ b/lib/Math/BigRat.pm @@ -1,4 +1,7 @@ -#!/usr/bin/perl -w + +# +# "Tax the rat farms." +# # The following hash values are used: # sign : +,-,NaN,+inf,-inf @@ -10,7 +13,7 @@ package Math::BigRat; -require 5.005_02; +require 5.005_03; use strict; use Exporter; @@ -21,7 +24,7 @@ use vars qw($VERSION @ISA $PACKAGE @EXPORT_OK $upgrade $downgrade @ISA = qw(Exporter Math::BigFloat); @EXPORT_OK = qw(); -$VERSION = '0.06'; +$VERSION = '0.07'; use overload; # inherit from Math::BigFloat @@ -70,7 +73,6 @@ sub _new_from_float # 1 / 1 => 10/1 $self->{_n}->blsft($f->{_e},10) unless $f->{_e}->is_zero(); } -# print "float new $self->{_n} / $self->{_d}\n"; $self; } @@ -83,26 +85,12 @@ sub new my $self = { }; bless $self,$class; -# print "ref ",ref($n),"\n"; -# if (ref($n)) -# { -# print "isa float " if $n->isa('Math::BigFloat'); -# print "isa int " if $n->isa('Math::BigInt'); -# print "isa rat " if $n->isa('Math::BigRat'); -# print "isa lite " if $n->isa('Math::BigInt::Lite'); -# } -# else -# { -# print "scalar $n\n"; -# } # input like (BigInt,BigInt) or (BigFloat,BigFloat) not handled yet if ((!defined $d) && (ref $n) && (!$n->isa('Math::BigRat'))) { -# print "is ref, but not rat\n"; if ($n->isa('Math::BigFloat')) { - # print "is ref, and float\n"; return $self->_new_from_float($n)->bnorm(); } if ($n->isa('Math::BigInt')) @@ -114,7 +102,6 @@ sub new } if ($n->isa('Math::BigInt::Lite')) { -# print "is ref, and lite\n"; $self->{_n} = $MBI->new($$n); # "mantissa" = $n $self->{_d} = $MBI->bone(); $self->{sign} = $self->{_n}->{sign}; $self->{_n}->{sign} = '+'; @@ -122,8 +109,6 @@ sub new } } return $n->copy() if ref $n; - -# print "is string\n"; if (!defined $n) { @@ -173,8 +158,9 @@ sub new # simple string input if (($n =~ /[\.eE]/)) { + # work around bug in BigFloat that makes 1.1.2 valid + return $self->bnan() if $n =~ /\..*\./; # looks like a float -# print "float-like string $d\n"; $self->_new_from_float(Math::BigFloat->new($n)); } else @@ -182,6 +168,8 @@ sub new $self->{_n} = $MBI->new($n); $self->{_d} = $MBI->bone(); $self->{sign} = $self->{_n}->{sign}; $self->{_n}->{sign} = '+'; + return $self->bnan() if $self->{sign} eq 'NaN'; + return $self->binf($self->{sign}) if $self->{sign} =~ /^[+-]inf$/; } $self->bnorm(); } @@ -198,7 +186,6 @@ sub bstr return $s; } -# print "bstr $x->{sign} $x->{_n} $x->{_d}\n"; my $s = ''; $s = $x->{sign} if $x->{sign} ne '+'; # +3 vs 3 return $s.$x->{_n}->bstr() if $x->{_d}->is_one(); @@ -238,8 +225,6 @@ sub bnorm $x->{_d}->{_a} = undef; $x->{_n}->{_a} = undef; $x->{_d}->{_p} = undef; $x->{_n}->{_p} = undef; -# print "$x->{sign} $x->{_n} / $x->{_d} => "; - # no normalize for NaN, inf etc. return $x if $x->{sign} !~ /^[+-]$/; @@ -247,27 +232,23 @@ sub bnorm if (($x->{sign} =~ /^[+-]$/) && ($x->{_n}->is_zero())) { - $x->{sign} = '+'; # never -0 + $x->{sign} = '+'; # never -0 $x->{_d} = $MBI->bone() unless $x->{_d}->is_one(); return $x; } - return $x if $x->{_d}->is_one(); + return $x if $x->{_d}->is_one(); # no need to reduce # reduce other numbers - # print "bgcd $x->{_n} (",ref($x->{_n}),") $x->{_d} (",ref($x->{_d}),")\n"; # disable upgrade in BigInt, otherwise deep recursion local $Math::BigInt::upgrade = undef; my $gcd = $x->{_n}->bgcd($x->{_d}); if (!$gcd->is_one()) { -# print "normalize $x->{_d} / $x->{_n} => "; $x->{_n}->bdiv($gcd); $x->{_d}->bdiv($gcd); -# print "$x->{_d} / $x->{_n}\n"; } -# print "$x->{_n} / $x->{_d}\n"; $x; } @@ -278,32 +259,32 @@ sub _bnan { # used by parent class bone() to initialize number to 1 my $self = shift; - $self->{_n} = Math::BigInt->bzero(); - $self->{_d} = Math::BigInt->bzero(); + $self->{_n} = $MBI->bzero(); + $self->{_d} = $MBI->bzero(); } sub _binf { # used by parent class bone() to initialize number to 1 my $self = shift; - $self->{_n} = Math::BigInt->bzero(); - $self->{_d} = Math::BigInt->bzero(); + $self->{_n} = $MBI->bzero(); + $self->{_d} = $MBI->bzero(); } sub _bone { # used by parent class bone() to initialize number to 1 my $self = shift; - $self->{_n} = Math::BigInt->bone(); - $self->{_d} = Math::BigInt->bone(); + $self->{_n} = $MBI->bone(); + $self->{_d} = $MBI->bone(); } sub _bzero { # used by parent class bone() to initialize number to 1 my $self = shift; - $self->{_n} = Math::BigInt->bzero(); - $self->{_d} = Math::BigInt->bone(); + $self->{_n} = $MBI->bzero(); + $self->{_d} = $MBI->bone(); } ############################################################################## @@ -314,13 +295,8 @@ sub badd # add two rationals my ($self,$x,$y,$a,$p,$r) = objectify(2,@_); -# print "rat badd\n"; -# print "ref($x) = ",ref($x),"\n"; -# print "ref($y) = ",ref($y),"\n"; $x = $self->new($x) unless $x->isa($self); $y = $self->new($y) unless $y->isa($self); -# print "ref($x) = ",ref($x),"\n"; -# print "ref($y) = ",ref($y),"\n"; return $x->bnan() if ($x->{sign} eq 'NaN' || $y->{sign} eq 'NaN'); @@ -434,7 +410,6 @@ sub bdiv $x = $class->new($x) unless $x->isa($class); $y = $class->new($y) unless $y->isa($class); -# print "rat bdiv $x $y ",ref($x)," ",ref($y),"\n"; return $self->_div_inf($x,$y) if (($x->{sign} !~ /^[+-]$/) || ($y->{sign} !~ /^[+-]$/) || $y->is_zero()); @@ -449,16 +424,75 @@ sub bdiv $x->{_n}->bmul($y->{_d}); $x->{_d}->bmul($y->{_n}); -# print "result $x->{_d} $x->{_n}\n"; # compute new sign $x->{sign} = $x->{sign} eq $y->{sign} ? '+' : '-'; $x->bnorm()->round($a,$p,$r); -# print "result $x->{_d} $x->{_n}\n"; $x; } ############################################################################## +# bdec/binc + +sub bdec + { + # decrement value (subtract 1) + my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_); + + return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf + + if ($x->{sign} eq '-') + { + $x->{_n}->badd($x->{_d}); # -5/2 => -7/2 + } + else + { + if ($x->{_n}->bacmp($x->{_d}) < 0) + { + # 1/3 -- => -2/3 + $x->{_n} = $x->{_d} - $x->{_n}; + $x->{sign} = '-'; + } + else + { + $x->{_n}->bsub($x->{_d}); # 5/2 => 3/2 + } + } + $x->bnorm()->round(@r); + + #$x->bsub($self->bone())->round(@r); + } + +sub binc + { + # increment value (add 1) + my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_); + + return $x if $x->{sign} !~ /^[+-]$/; # NaN, inf, -inf + + if ($x->{sign} eq '-') + { + if ($x->{_n}->bacmp($x->{_d}) < 0) + { + # -1/3 ++ => 2/3 (overflow at 0) + $x->{_n} = $x->{_d} - $x->{_n}; + $x->{sign} = '+'; + } + else + { + $x->{_n}->bsub($x->{_d}); # -5/2 => -3/2 + } + } + else + { + $x->{_n}->badd($x->{_d}); # 5/2 => 7/2 + } + $x->bnorm()->round(@r); + + #$x->badd($self->bone())->round(@r); + } + +############################################################################## # is_foo methods (the rest is inherited) sub is_int @@ -523,7 +557,9 @@ BEGIN sub numerator { my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_); - + + return $MBI->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/); + my $n = $x->{_n}->copy(); $n->{sign} = $x->{sign}; $n; } @@ -532,6 +568,7 @@ sub denominator { my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_); + return $MBI->new($x->{sign}) if ($x->{sign} !~ /^[+-]$/); $x->{_d}->copy(); } @@ -539,9 +576,13 @@ sub parts { my ($self,$x) = ref($_[0]) ? (ref($_[0]),$_[0]) : objectify(1,@_); + return ($self->bnan(),$self->bnan()) if $x->{sign} eq 'NaN'; + return ($self->binf(),$self->binf()) if $x->{sign} eq '+inf'; + return ($self->binf('-'),$self->binf()) if $x->{sign} eq '-inf'; + my $n = $x->{_n}->copy(); $n->{sign} = $x->{sign}; - return ($x->{_n}->copy(),$x->{_d}->copy()); + return ($n,$x->{_d}->copy()); } sub length @@ -564,9 +605,10 @@ sub bceil return $x unless $x->{sign} =~ /^[+-]$/; return $x if $x->{_d}->is_one(); # 22/1 => 22, 0/1 => 0 - $x->{_n}->bdiv($x->{_d}); # 22/7 => 3/1 + $x->{_n}->bdiv($x->{_d}); # 22/7 => 3/1 w/ truncate $x->{_d}->bone(); $x->{_n}->binc() if $x->{sign} eq '+'; # +22/7 => 4/1 + $x->{sign} = '+' if $x->{_n}->is_zero(); # -0 => 0 $x; } @@ -577,7 +619,7 @@ sub bfloor return $x unless $x->{sign} =~ /^[+-]$/; return $x if $x->{_d}->is_one(); # 22/1 => 22, 0/1 => 0 - $x->{_n}->bdiv($x->{_d}); # 22/7 => 3/1 + $x->{_n}->bdiv($x->{_d}); # 22/7 => 3/1 w/ truncate $x->{_d}->bone(); $x->{_n}->binc() if $x->{sign} eq '-'; # -22/7 => -4/1 $x; @@ -585,7 +627,14 @@ sub bfloor sub bfac { - return Math::BigRat->bnan(); + my ($self,$x,@r) = ref($_[0]) ? (ref($_[0]),@_) : objectify(1,@_); + + if (($x->{sign} eq '+') && ($x->{_d}->is_one())) + { + $x->{_n}->bfac(); + return $x->round(@r); + } + $x->bnan(); } sub bpow @@ -607,12 +656,49 @@ sub bpow # return $x->bnan() if $y->{sign} eq '-'; return $x->round(@r) if $x->is_zero(); # 0**y => 0 (if not y <= 0) + # shortcut y/1 (and/or x/1) + if ($y->{_d}->is_one()) + { + # shortcut for x/1 and y/1 + if ($x->{_d}->is_one()) + { + $x->{_n}->bpow($y->{_n}); # x/1 ** y/1 => (x ** y)/1 + if ($y->{sign} eq '-') + { + # 0.2 ** -3 => 1/(0.2 ** 3) + ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap + } + # correct sign; + ** + => + + if ($x->{sign} eq '-') + { + # - * - => +, - * - * - => - + $x->{sign} = '+' if $y->{_n}->is_even(); + } + return $x->round(@r); + } + # x/z ** y/1 + $x->{_n}->bpow($y->{_n}); # 5/2 ** y/1 => 5 ** y / 2 ** y + $x->{_d}->bpow($y->{_n}); + if ($y->{sign} eq '-') + { + # 0.2 ** -3 => 1/(0.2 ** 3) + ($x->{_n},$x->{_d}) = ($x->{_d},$x->{_n}); # swap + } + # correct sign; + ** + => + + if ($x->{sign} eq '-') + { + # - * - => +, - * - * - => - + $x->{sign} = '+' if $y->{_n}->is_even(); + } + return $x->round(@r); + } + + # regular calculation (this is wrong for d/e ** f/g) my $pow2 = $self->__one(); - my $y1 = Math::BigInt->new($y->{_n}/$y->{_d})->babs(); - my $two = Math::BigInt->new(2); + my $y1 = $MBI->new($y->{_n}/$y->{_d})->babs(); + my $two = $MBI->new(2); while (!$y1->is_one()) { - print "at $y1 (= $x)\n"; $pow2->bmul($x) if $y1->is_odd(); $y1->bdiv($two); $x->bmul($x); @@ -786,13 +872,9 @@ sub import } else { - # MBI not loaded, or with ne "Math::BigInt" + # MBI not loaded, or not with "Math::BigInt" $lib .= ",$mbilib" if defined $mbilib; -# my @parts = split /::/, $MBI; # Math::BigInt => Math BigInt -# my $file = pop @parts; $file .= '.pm'; # BigInt => BigInt.pm -# $file = File::Spec->catfile (@parts, $file); - if ($] < 5.006) { # Perl < 5.6.0 dies with "out of memory!" when eval() and ':constant' is @@ -902,33 +984,29 @@ BigInts. Returns a copy of the object as BigInt by truncating it to integer. -=head2 bfac()/blog() +=head2 bfac() -Are not yet implemented. - -=head2 bround()/round()/bfround() - -Are not yet implemented. + $x->bfac(); +Calculates the factorial of $x. For instance: -=head1 BUGS + print Math::BigRat->new('3/1')->bfac(),"\n"; # 1*2*3 + print Math::BigRat->new('5/1')->bfac(),"\n"; # 1*2*3*4*5 -=over 2 +Only works for integers for now. -=item perl -Mbigrat -le 'print 1 + 2/3' +=head2 blog() -This produces wrongly NaN. It is unclear why. The following variants all work: +Is not yet implemented. - perl -Mbigrat -le 'print 1/3 + 2/3' - perl -Mbigrat -le 'print 1/3 + 2' +=head2 bround()/round()/bfround() -This also does not work: +Are not yet implemented. - perl -Mbigrat -le 'print 1+3+1/2' -=back +=head1 BUGS -Please see also L. +Some things are not yet implemented, or only implemented half-way. =head1 LICENSE diff --git a/lib/Math/BigRat/t/bigfltpm.inc b/lib/Math/BigRat/t/bigfltpm.inc index 5b3f4f1..36bb35d 100644 --- a/lib/Math/BigRat/t/bigfltpm.inc +++ b/lib/Math/BigRat/t/bigfltpm.inc @@ -4,7 +4,7 @@ ok ($class->config()->{lib},$CL); while () { - chop; + chomp; $_ =~ s/#.*$//; # remove comments $_ =~ s/\s+$//; # trailing spaces next if /^$/; # skip empty lines & comments @@ -1054,10 +1054,10 @@ abc:1:abc:NaN 152403346:12345:4321 87654321:87654321:0 # now some floating point tests -123:2.5:0.5 -1230:2.5:0 -123.4:2.5:0.9 -123e1:25:5 +#123:2.5:0.5 +#1230:2.5:0 +#123.4:2.5:0.9 +#123e1:25:5 &ffac Nanfac:NaN -1:NaN diff --git a/lib/Math/BigRat/t/bigfltrt.t b/lib/Math/BigRat/t/bigfltrt.t index a456320..d408b23 100755 --- a/lib/Math/BigRat/t/bigfltrt.t +++ b/lib/Math/BigRat/t/bigfltrt.t @@ -41,4 +41,4 @@ $CL = "Math::BigInt::Calc"; ok (1,1); # does not fully work yet -# require 'bigfltpm.inc'; # all tests here for sharing +#require 'bigfltpm.inc'; # all tests here for sharing diff --git a/lib/Math/BigRat/t/bigrat.t b/lib/Math/BigRat/t/bigrat.t index f1aba64..b59d9f0 100755 --- a/lib/Math/BigRat/t/bigrat.t +++ b/lib/Math/BigRat/t/bigrat.t @@ -8,7 +8,7 @@ BEGIN $| = 1; chdir 't' if -d 't'; unshift @INC, '../lib'; # for running manually - plan tests => 83; + plan tests => 136; } # testing of Math::BigRat @@ -45,99 +45,151 @@ foreach my $func (qw/new bnorm/) $x = $cr->$func('0.1/0.1'); ok ($x,'1'); $x = $cr->$func('1e2/10'); ok ($x,10); $x = $cr->$func('1e2/1e1'); ok ($x,10); - $x = $cr->$func('1 / 3'); ok ($x,'1/3'); + $x = $cr->$func('1 / 3'); ok ($x,'1/3'); $x = $cr->$func('-1 / 3'); ok ($x,'-1/3'); - $x = $cr->$func('NaN'); ok ($x,'NaN'); - $x = $cr->$func('inf'); ok ($x,'inf'); - $x = $cr->$func('-inf'); ok ($x,'-inf'); - $x = $cr->$func('1/'); ok ($x,'NaN'); + $x = $cr->$func('NaN'); ok ($x,'NaN'); + $x = $cr->$func('inf'); ok ($x,'inf'); + $x = $cr->$func('-inf'); ok ($x,'-inf'); + $x = $cr->$func('1/'); ok ($x,'NaN'); # input ala '1+1/3' isn't parsed ok yet - $x = $cr->$func('1+1/3'); ok ($x,'NaN'); + $x = $cr->$func('1+1/3'); ok ($x,'NaN'); ############################################################################ # other classes as input - $x = $cr->$func($mbi->new(1231)); ok ($x,'1231'); - $x = $cr->$func($mbf->new(1232)); ok ($x,'1232'); + $x = $cr->$func($mbi->new(1231)); ok ($x,'1231'); + $x = $cr->$func($mbf->new(1232)); ok ($x,'1232'); $x = $cr->$func($mbf->new(1232.3)); ok ($x,'12323/10'); } + +$x = $cr->new('-0'); ok ($x,'0'); ok ($x->{_n}, '0'); ok ($x->{_d},'1'); +$x = $cr->new('NaN'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +$x = $cr->new('-NaN'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +$x = $cr->new('-1r4'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); + +$x = $cr->new('+inf'); ok ($x,'inf'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +$x = $cr->new('-inf'); ok ($x,'-inf'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +$x = $cr->new('123a4'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); + +# wrong inputs +$x = $cr->new('1e2e2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +$x = $cr->new('1+2+2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); +# failed due to BigFlaot bug +$x = $cr->new('1.2.2'); ok ($x,'NaN'); ok ($x->{_n}, '0'); ok ($x->{_d},'0'); + +ok ($cr->new('123a4'),'NaN'); +ok ($cr->new('123e4'),'1230000'); +ok ($cr->new('-NaN'),'NaN'); +ok ($cr->new('NaN'),'NaN'); +ok ($cr->new('+inf'),'inf'); +ok ($cr->new('-inf'),'-inf'); ############################################################################## # mixed arguments -ok (Math::BigRat->new('3/7')->badd(1),'10/7'); -ok (Math::BigRat->new('3/10')->badd(1.1),'7/5'); -ok (Math::BigRat->new('3/7')->badd(Math::BigInt->new(1)),'10/7'); -ok (Math::BigRat->new('3/10')->badd(Math::BigFloat->new('1.1')),'7/5'); +ok ($cr->new('3/7')->badd(1),'10/7'); +ok ($cr->new('3/10')->badd(1.1),'7/5'); +ok ($cr->new('3/7')->badd($mbi->new(1)),'10/7'); +ok ($cr->new('3/10')->badd($mbf->new('1.1')),'7/5'); -ok (Math::BigRat->new('3/7')->bsub(1),'-4/7'); -ok (Math::BigRat->new('3/10')->bsub(1.1),'-4/5'); -ok (Math::BigRat->new('3/7')->bsub(Math::BigInt->new(1)),'-4/7'); -ok (Math::BigRat->new('3/10')->bsub(Math::BigFloat->new('1.1')),'-4/5'); +ok ($cr->new('3/7')->bsub(1),'-4/7'); +ok ($cr->new('3/10')->bsub(1.1),'-4/5'); +ok ($cr->new('3/7')->bsub($mbi->new(1)),'-4/7'); +ok ($cr->new('3/10')->bsub($mbf->new('1.1')),'-4/5'); -ok (Math::BigRat->new('3/7')->bmul(1),'3/7'); -ok (Math::BigRat->new('3/10')->bmul(1.1),'33/100'); -ok (Math::BigRat->new('3/7')->bmul(Math::BigInt->new(1)),'3/7'); -ok (Math::BigRat->new('3/10')->bmul(Math::BigFloat->new('1.1')),'33/100'); +ok ($cr->new('3/7')->bmul(1),'3/7'); +ok ($cr->new('3/10')->bmul(1.1),'33/100'); +ok ($cr->new('3/7')->bmul($mbi->new(1)),'3/7'); +ok ($cr->new('3/10')->bmul($mbf->new('1.1')),'33/100'); -ok (Math::BigRat->new('3/7')->bdiv(1),'3/7'); -ok (Math::BigRat->new('3/10')->bdiv(1.1),'3/11'); -ok (Math::BigRat->new('3/7')->bdiv(Math::BigInt->new(1)),'3/7'); -ok (Math::BigRat->new('3/10')->bdiv(Math::BigFloat->new('1.1')),'3/11'); +ok ($cr->new('3/7')->bdiv(1),'3/7'); +ok ($cr->new('3/10')->bdiv(1.1),'3/11'); +ok ($cr->new('3/7')->bdiv($mbi->new(1)),'3/7'); +ok ($cr->new('3/10')->bdiv($mbf->new('1.1')),'3/11'); ############################################################################## -$x = Math::BigRat->new('1/4'); $y = Math::BigRat->new('1/3'); +$x = $cr->new('1/4'); $y = $cr->new('1/3'); ok ($x + $y, '7/12'); ok ($x * $y, '1/12'); ok ($x / $y, '3/4'); -$x = Math::BigRat->new('7/5'); $x *= '3/2'; +$x = $cr->new('7/5'); $x *= '3/2'; ok ($x,'21/10'); $x -= '0.1'; ok ($x,'2'); # not 21/10 -$x = Math::BigRat->new('2/3'); $y = Math::BigRat->new('3/2'); +$x = $cr->new('2/3'); $y = $cr->new('3/2'); ok ($x > $y,''); ok ($x < $y,1); ok ($x == $y,''); -$x = Math::BigRat->new('-2/3'); $y = Math::BigRat->new('3/2'); +$x = $cr->new('-2/3'); $y = $cr->new('3/2'); ok ($x > $y,''); ok ($x < $y,'1'); ok ($x == $y,''); -$x = Math::BigRat->new('-2/3'); $y = Math::BigRat->new('-2/3'); +$x = $cr->new('-2/3'); $y = $cr->new('-2/3'); ok ($x > $y,''); ok ($x < $y,''); ok ($x == $y,'1'); -$x = Math::BigRat->new('-2/3'); $y = Math::BigRat->new('-1/3'); +$x = $cr->new('-2/3'); $y = $cr->new('-1/3'); ok ($x > $y,''); ok ($x < $y,'1'); ok ($x == $y,''); -$x = Math::BigRat->new('-124'); $y = Math::BigRat->new('-122'); +$x = $cr->new('-124'); $y = $cr->new('-122'); ok ($x->bacmp($y),1); -$x = Math::BigRat->new('-124'); $y = Math::BigRat->new('-122'); +$x = $cr->new('-124'); $y = $cr->new('-122'); ok ($x->bcmp($y),-1); -$x = Math::BigRat->new('3/7'); $y = Math::BigRat->new('5/7'); +$x = $cr->new('3/7'); $y = $cr->new('5/7'); ok ($x+$y,'8/7'); -$x = Math::BigRat->new('3/7'); $y = Math::BigRat->new('5/7'); +$x = $cr->new('3/7'); $y = $cr->new('5/7'); ok ($x*$y,'15/49'); -$x = Math::BigRat->new('3/5'); $y = Math::BigRat->new('5/7'); +$x = $cr->new('3/5'); $y = $cr->new('5/7'); ok ($x*$y,'3/7'); -$x = Math::BigRat->new('3/5'); $y = Math::BigRat->new('5/7'); +$x = $cr->new('3/5'); $y = $cr->new('5/7'); ok ($x/$y,'21/25'); -$x = Math::BigRat->new('-144/9'); $x->bsqrt(); ok ($x,'NaN'); -$x = Math::BigRat->new('144/9'); $x->bsqrt(); ok ($x,'4'); +$x = $cr->new('-144/9')->bsqrt(); ok ($x,'NaN'); +$x = $cr->new('144/9')->bsqrt(); ok ($x,'4'); +############################################################################## +# bpow + +$x = $cr->new('2/1'); $z = $x->bpow('3/1'); ok ($x,'8'); + +############################################################################## +# bfac + +$x = $cr->new('1'); $x->bfac(); ok ($x,'1'); +for (my $i = 0; $i < 8; $i++) + { + $x = $cr->new("$i/1")->bfac(); ok ($x,$mbi->new($i)->bfac()); + } + +# test for $self->bnan() vs. $x->bnan(); +$x = $cr->new('-1'); $x->bfac(); ok ($x,'NaN'); + +############################################################################## +# binc/bdec + +$x = $cr->new('3/2'); ok ($x->binc(),'5/2'); +$x = $cr->new('15/6'); ok ($x->bdec(),'3/2'); + +############################################################################## +# bfloor/bceil + +$x = $cr->new('-7/7'); ok ($x->{_n}, '1'); ok ($x->{_d}, '1'); +$x = $cr->new('-7/7')->bfloor(); ok ($x->{_n}, '1'); ok ($x->{_d}, '1'); + +############################################################################## # done 1; diff --git a/lib/Math/BigRat/t/bigratpm.inc b/lib/Math/BigRat/t/bigratpm.inc index bbec697..0f77c33 100644 --- a/lib/Math/BigRat/t/bigratpm.inc +++ b/lib/Math/BigRat/t/bigratpm.inc @@ -4,7 +4,7 @@ ok ($class->config()->{lib},$CL); while () { - chop; + chomp; $_ =~ s/#.*$//; # remove comments $_ =~ s/\s+$//; # trailing spaces next if /^$/; # skip empty lines & comments @@ -87,6 +87,8 @@ while () $try .= '$x->bacmp($y);'; } elsif ($f eq "bpow") { $try .= '$x ** $y;'; + } elsif ($f eq "fpow") { + $try .= '$x->bpow($y);'; } elsif ($f eq "badd") { $try .= '$x + $y;'; } elsif ($f eq "bsub") { @@ -568,15 +570,17 @@ NaN:0 NaN:0 -inf:1 +inf:0 -#&parts -#0:0 1 -#1:1 0 -#123:123 0 -#-123:-123 0 -#-1200:-12 2 -#NaNparts:NaN NaN -#+inf:inf inf -#-inf:-inf inf +&parts +0:0 1 +1:1 1 +123:123 1 +-123:-123 1 +-1200:-1200 1 +5/7:5 7 +-5/7:-5 7 +NaNparts:NaN NaN ++inf:inf inf +-inf:-inf inf #&exponent #0:1 #1:0 @@ -631,6 +635,20 @@ abc:NaN -51:-51 -51.2:-52 12.2:12 +3/7:0 +6/7:0 +7/7:1 +8/7:1 +13/7:1 +14/7:2 +15/7:2 +-3/7:-1 +-6/7:-1 +-7/1:-7 +-8/7:-2 +-13/7:-2 +-14/7:-2 +-15/7:-3 &fceil 0:0 abc:NaN @@ -640,3 +658,64 @@ abc:NaN -51:-51 -51.2:-51 12.2:13 +3/7:1 +6/7:1 +8/7:2 +13/7:2 +14/7:2 +15/7:3 +-3/7:0 +-6/7:0 +-8/7:-1 +-13/7:-1 +-14/7:-2 +-15/7:-2 +&ffac +NaN:NaN +1:1 +-1:NaN +&bpow +# bpow test for overload of ** +2:2:4 +3:3:27 +&fpow +2/1:3/1:8 +3/1:3/1:27 +5/2:3/1:125/8 +-2/1:3/1:-8 +-3/1:3/1:-27 +-5/2:3/1:-125/8 +-2/1:4/1:16 +-3/1:4/1:81 +-5/2:4/1:625/16 +-5/2:-4/1:16/625 +1/5:-3:125 +-1/5:-3:-125 +&numerator +NaN:NaN +inf:inf +-inf:-inf +3/7:3 +-3/7:-3 +0:0 +1:1 +&denominator +NaN:NaN +inf:inf +-inf:-inf +3/7:7 +0:1 +1/1:1 +-3/7:7 +&finc +3/2:5/2 +-15/6:-3/2 +NaN:NaN +-1/3:2/3 +-2/7:5/7 +&fdec +15/6:3/2 +-3/2:-5/2 +1/3:-2/3 +2/7:-5/7 +NaN:NaN diff --git a/lib/Math/BigRat/t/bigratpm.t b/lib/Math/BigRat/t/bigratpm.t index 37c431c..1ef0a88 100755 --- a/lib/Math/BigRat/t/bigratpm.t +++ b/lib/Math/BigRat/t/bigratpm.t @@ -26,7 +26,7 @@ BEGIN } print "# INC = @INC\n"; - plan tests => 414; + plan tests => 491; } use Math::BigRat;