From: Steven Knight Date: Mon, 8 Feb 1999 01:16:24 +0000 (-0600) Subject: fix bugs in the handling of negative numbers, among other things X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5d7098d560a042a848a6e60f96567ce4b694c6c7;p=p5sagit%2Fp5-mst-13.2.git fix bugs in the handling of negative numbers, among other things Message-Id: <199902080716.BAA24652@theopera.baldmt.citilink.com> Subject: Math::BigFloat and Math::BigInt p4raw-id: //depot/perl@2934 --- diff --git a/lib/Math/BigFloat.pm b/lib/Math/BigFloat.pm index 3f394fb..56d6efe 100644 --- a/lib/Math/BigFloat.pm +++ b/lib/Math/BigFloat.pm @@ -9,10 +9,8 @@ use overload '+' => sub {new Math::BigFloat &fadd}, '-' => sub {new Math::BigFloat $_[2]? fsub($_[1],${$_[0]}) : fsub(${$_[0]},$_[1])}, -'<=>' => sub {new Math::BigFloat - $_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])}, -'cmp' => sub {new Math::BigFloat - $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, +'<=>' => sub {$_[2]? fcmp($_[1],${$_[0]}) : fcmp(${$_[0]},$_[1])}, +'cmp' => sub {$_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, '*' => sub {new Math::BigFloat &fmul}, '/' => sub {new Math::BigFloat $_[2]? scalar fdiv($_[1],${$_[0]}) : @@ -159,7 +157,8 @@ sub fdiv #(fnum_str, fnum_str[,scale]) return fnum_str $scale = length($xm)-1 if (length($xm)-1 > $scale); $scale = length($ym)-1 if (length($ym)-1 > $scale); $scale = $scale + length($ym) - length($xm); - &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym),$ym), + &norm(&round(Math::BigInt::bdiv($xm.('0' x $scale),$ym), + Math::BigInt::babs($ym)), $xe-$ye-$scale); } } @@ -219,7 +218,11 @@ sub ffround { #(fnum_str, scale) return fnum_str if ($xe < 1) { '+0E+0'; } elsif ($xe == 1) { - &norm(&round('+0',"+0".substr($xm,$[+1,1),"+10"), $scale); + # The first substr preserves the sign, passing a non- + # normalized "-0" to &round when rounding -0.006 (for + # example), purely so &round won't lose the sign. + &norm(&round(substr($xm,$[,1).'0', + "+0".substr($xm,$[+1,1),"+10"), $scale); } else { &norm(&round(substr($xm,$[,$xe), "+0".substr($xm,$[+$xe,1),"+10"), $scale); @@ -310,9 +313,24 @@ negative number. =item Division is computed to -C digits by default. +C +digits by default. Also used for default sqrt scale. +=item Rounding is performed + +according to the value of +C<$Math::BigFloat::rnd_mode>: + + trunc truncate the value + zero round towards 0 + +inf round towards +infinity (round up) + -inf round towards -infinity (round down) + even round to the nearest, .5 to the even digit + odd round to the nearest, .5 to the odd digit + +The default is C rounding. + =back =head1 BUGS @@ -320,6 +338,15 @@ Also used for default sqrt scale. The current version of this module is a preliminary version of the real thing that is currently (as of perl5.002) under development. +The printf subroutine does not use the value of +C<$Math::BigFloat::rnd_mode> when rounding values for printing. +Consequently, the way to print rounded values is +to specify the number of digits both as an +argument to C and in the C<%f> printf string, +as follows: + + printf "%.3f\n", $bigfloat->ffround(-3); + =head1 AUTHOR Mark Biggar diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm index b61b884..b8ad6ce 100644 --- a/lib/Math/BigInt.pm +++ b/lib/Math/BigInt.pm @@ -4,10 +4,8 @@ use overload '+' => sub {new Math::BigInt &badd}, '-' => sub {new Math::BigInt $_[2]? bsub($_[1],${$_[0]}) : bsub(${$_[0]},$_[1])}, -'<=>' => sub {new Math::BigInt - $_[2]? bcmp($_[1],${$_[0]}) : bcmp(${$_[0]},$_[1])}, -'cmp' => sub {new Math::BigInt - $_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, +'<=>' => sub {$_[2]? bcmp($_[1],${$_[0]}) : bcmp(${$_[0]},$_[1])}, +'cmp' => sub {$_[2]? ($_[1] cmp ${$_[0]}) : (${$_[0]} cmp $_[1])}, '*' => sub {new Math::BigInt &bmul}, '/' => sub {new Math::BigInt $_[2]? scalar bdiv($_[1],${$_[0]}) : @@ -258,9 +256,9 @@ sub bdiv { #(dividend: num_str, divisor: num_str) return num_str else { push(@x, 0); } - @q = (); ($v2,$v1) = ($y[-2] || 0, $y[-1]); + @q = (); ($v2,$v1) = @y[-2,-1]; while ($#x > $#y) { - ($u2,$u1,$u0) = ($x[-3] || 0, $x[-2] || 0, $x[-1]); + ($u2,$u1,$u0) = @x[-3..-1]; $q = (($u0 == $v1) ? 99999 : int(($u0*1e5+$u1)/$v1)); --$q while ($v2*$q > ($u0*1e5+$u1-$q*$v1)*1e5+$u2); if ($q) { diff --git a/lib/bigfloat.pl b/lib/bigfloat.pl index d687c78..032dfe6 100644 --- a/lib/bigfloat.pl +++ b/lib/bigfloat.pl @@ -6,7 +6,7 @@ require "bigint.pl"; # # number format # canonical strings have the form /[+-]\d+E[+-]\d+/ -# Input values can have inbedded whitespace +# Input values can have embedded whitespace # Error returns # 'NaN' An input parameter was "Not a Number" or # divide by zero or sqrt of negative number @@ -126,7 +126,7 @@ sub main'fdiv #(fnum_str, fnum_str[,scale]) return fnum_str $scale = length($xm)-1 if (length($xm)-1 > $scale); $scale = length($ym)-1 if (length($ym)-1 > $scale); $scale = $scale + length($ym) - length($xm); - &norm(&round(&'bdiv($xm.('0' x $scale),$ym),$ym), + &norm(&round(&'bdiv($xm.('0' x $scale),$ym),&'babs($ym)), $xe-$ye-$scale); } } @@ -186,7 +186,12 @@ sub main'ffround { #(fnum_str, scale) return fnum_str if ($xe < 1) { '+0E+0'; } elsif ($xe == 1) { - &norm(&round('+0',"+0".substr($xm,$[+1,1),"+10"), $scale); + # The first substr preserves the sign, which means that + # we'll pass a non-normalized "-0" to &round when rounding + # -0.006 (for example), purely so that &round won't lose + # the sign. + &norm(&round(substr($xm,$[,1).'0', + "+0".substr($xm,$[+1,1),"+10"), $scale); } else { &norm(&round(substr($xm,$[,$xe), "+0".substr($xm,$[+$xe,1),"+10"), $scale); diff --git a/t/lib/bigfloat.t b/t/lib/bigfloat.t new file mode 100755 index 0000000..8e0a0ef --- /dev/null +++ b/t/lib/bigfloat.t @@ -0,0 +1,408 @@ +#!./perl + +BEGIN { @INC = '../lib' } +require "bigfloat.pl"; + +$test = 0; +$| = 1; +print "1..355\n"; +while () { + chop; + if (/^&/) { + $f = $_; + } elsif (/^\$.*/) { + eval "$_;"; + } else { + ++$test; + @args = split(/:/,$_,99); + $ans = pop(@args); + $try = "$f('" . join("','", @args) . "');"; + if (($ans1 = eval($try)) eq $ans) { + print "ok $test\n"; + } else { + print "not ok $test\n"; + print "# '$try' expected: '$ans' got: '$ans1'\n"; + } + } +} +__END__ +&fnorm +abc:NaN + 1 a:NaN +1bcd2:NaN +11111b:NaN ++1z:NaN +-1z:NaN +0:+0E+0 ++0:+0E+0 ++00:+0E+0 ++0 0 0:+0E+0 +000000 0000000 00000:+0E+0 +-0:+0E+0 +-0000:+0E+0 ++1:+1E+0 ++01:+1E+0 ++001:+1E+0 ++00000100000:+1E+5 +123456789:+123456789E+0 +-1:-1E+0 +-01:-1E+0 +-001:-1E+0 +-123456789:-123456789E+0 +-00000100000:-1E+5 +123.456a:NaN +123.456:+123456E-3 +0.01:+1E-2 +.002:+2E-3 +-0.0003:-3E-4 +-.0000000004:-4E-10 +123456E2:+123456E+2 +123456E-2:+123456E-2 +-123456E2:-123456E+2 +-123456E-2:-123456E-2 +1e1:+1E+1 +2e-11:+2E-11 +-3e111:-3E+111 +-4e-1111:-4E-1111 +&fneg +abd:NaN ++0:+0E+0 ++1:-1E+0 +-1:+1E+0 ++123456789:-123456789E+0 +-123456789:+123456789E+0 ++123.456789:-123456789E-6 +-123456.789:+123456789E-3 +&fabs +abc:NaN ++0:+0E+0 ++1:+1E+0 +-1:+1E+0 ++123456789:+123456789E+0 +-123456789:+123456789E+0 ++123.456789:+123456789E-6 +-123456.789:+123456789E-3 +&fround +$bigfloat::rnd_mode = 'trunc' ++10123456789:5:+10123E+6 +-10123456789:5:-10123E+6 ++10123456789:9:+101234567E+2 +-10123456789:9:-101234567E+2 ++101234500:6:+101234E+3 +-101234500:6:-101234E+3 +$bigfloat::rnd_mode = 'zero' ++20123456789:5:+20123E+6 +-20123456789:5:-20123E+6 ++20123456789:9:+201234568E+2 +-20123456789:9:-201234568E+2 ++201234500:6:+201234E+3 +-201234500:6:-201234E+3 +$bigfloat::rnd_mode = '+inf' ++30123456789:5:+30123E+6 +-30123456789:5:-30123E+6 ++30123456789:9:+301234568E+2 +-30123456789:9:-301234568E+2 ++301234500:6:+301235E+3 +-301234500:6:-301234E+3 +$bigfloat::rnd_mode = '-inf' ++40123456789:5:+40123E+6 +-40123456789:5:-40123E+6 ++40123456789:9:+401234568E+2 +-40123456789:9:-401234568E+2 ++401234500:6:+401234E+3 +-401234500:6:-401235E+3 +$bigfloat::rnd_mode = 'odd' ++50123456789:5:+50123E+6 +-50123456789:5:-50123E+6 ++50123456789:9:+501234568E+2 +-50123456789:9:-501234568E+2 ++501234500:6:+501235E+3 +-501234500:6:-501235E+3 +$bigfloat::rnd_mode = 'even' ++60123456789:5:+60123E+6 +-60123456789:5:-60123E+6 ++60123456789:9:+601234568E+2 +-60123456789:9:-601234568E+2 ++601234500:6:+601234E+3 +-601234500:6:-601234E+3 +&ffround +$bigfloat::rnd_mode = 'trunc' ++1.23:-1:+12E-1 +-1.23:-1:-12E-1 ++1.27:-1:+12E-1 +-1.27:-1:-12E-1 ++1.25:-1:+12E-1 +-1.25:-1:-12E-1 ++1.35:-1:+13E-1 +-1.35:-1:-13E-1 +-0.006:-1:+0E+0 +-0.006:-2:+0E+0 +$bigfloat::rnd_mode = 'zero' ++2.23:-1:+22E-1 +-2.23:-1:-22E-1 ++2.27:-1:+23E-1 +-2.27:-1:-23E-1 ++2.25:-1:+22E-1 +-2.25:-1:-22E-1 ++2.35:-1:+23E-1 +-2.35:-1:-23E-1 +-0.0065:-1:+0E+0 +-0.0065:-2:-1E-2 +-0.0065:-3:-6E-3 +-0.0065:-4:-65E-4 +-0.0065:-5:-65E-4 +$bigfloat::rnd_mode = '+inf' ++3.23:-1:+32E-1 +-3.23:-1:-32E-1 ++3.27:-1:+33E-1 +-3.27:-1:-33E-1 ++3.25:-1:+33E-1 +-3.25:-1:-32E-1 ++3.35:-1:+34E-1 +-3.35:-1:-33E-1 +-0.0065:-1:+0E+0 +-0.0065:-2:-1E-2 +-0.0065:-3:-6E-3 +-0.0065:-4:-65E-4 +-0.0065:-5:-65E-4 +$bigfloat::rnd_mode = '-inf' ++4.23:-1:+42E-1 +-4.23:-1:-42E-1 ++4.27:-1:+43E-1 +-4.27:-1:-43E-1 ++4.25:-1:+42E-1 +-4.25:-1:-43E-1 ++4.35:-1:+43E-1 +-4.35:-1:-44E-1 +-0.0065:-1:+0E+0 +-0.0065:-2:-1E-2 +-0.0065:-3:-7E-3 +-0.0065:-4:-65E-4 +-0.0065:-5:-65E-4 +$bigfloat::rnd_mode = 'odd' ++5.23:-1:+52E-1 +-5.23:-1:-52E-1 ++5.27:-1:+53E-1 +-5.27:-1:-53E-1 ++5.25:-1:+53E-1 +-5.25:-1:-53E-1 ++5.35:-1:+53E-1 +-5.35:-1:-53E-1 +-0.0065:-1:+0E+0 +-0.0065:-2:-1E-2 +-0.0065:-3:-7E-3 +-0.0065:-4:-65E-4 +-0.0065:-5:-65E-4 +$bigfloat::rnd_mode = 'even' ++6.23:-1:+62E-1 +-6.23:-1:-62E-1 ++6.27:-1:+63E-1 +-6.27:-1:-63E-1 ++6.25:-1:+62E-1 +-6.25:-1:-62E-1 ++6.35:-1:+64E-1 +-6.35:-1:-64E-1 +-0.0065:-1:+0E+0 +-0.0065:-2:-1E-2 +-0.0065:-3:-6E-3 +-0.0065:-4:-65E-4 +-0.0065:-5:-65E-4 +&fcmp +abc:abc: +abc:+0: ++0:abc: ++0:+0:0 +-1:+0:-1 ++0:-1:1 ++1:+0:1 ++0:+1:-1 +-1:+1:-1 ++1:-1:1 +-1:-1:0 ++1:+1:0 ++123:+123:0 ++123:+12:1 ++12:+123:-1 +-123:-123:0 +-123:-12:-1 +-12:-123:1 ++123:+124:-1 ++124:+123:1 +-123:-124:1 +-124:-123:-1 +&fadd +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:+0E+0 ++1:+0:+1E+0 ++0:+1:+1E+0 ++1:+1:+2E+0 +-1:+0:-1E+0 ++0:-1:-1E+0 +-1:-1:-2E+0 +-1:+1:+0E+0 ++1:-1:+0E+0 ++9:+1:+1E+1 ++99:+1:+1E+2 ++999:+1:+1E+3 ++9999:+1:+1E+4 ++99999:+1:+1E+5 ++999999:+1:+1E+6 ++9999999:+1:+1E+7 ++99999999:+1:+1E+8 ++999999999:+1:+1E+9 ++9999999999:+1:+1E+10 ++99999999999:+1:+1E+11 ++10:-1:+9E+0 ++100:-1:+99E+0 ++1000:-1:+999E+0 ++10000:-1:+9999E+0 ++100000:-1:+99999E+0 ++1000000:-1:+999999E+0 ++10000000:-1:+9999999E+0 ++100000000:-1:+99999999E+0 ++1000000000:-1:+999999999E+0 ++10000000000:-1:+9999999999E+0 ++123456789:+987654321:+111111111E+1 +-123456789:+987654321:+864197532E+0 +-123456789:-987654321:-111111111E+1 ++123456789:-987654321:-864197532E+0 +&fsub +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:+0E+0 ++1:+0:+1E+0 ++0:+1:-1E+0 ++1:+1:+0E+0 +-1:+0:-1E+0 ++0:-1:+1E+0 +-1:-1:+0E+0 +-1:+1:-2E+0 ++1:-1:+2E+0 ++9:+1:+8E+0 ++99:+1:+98E+0 ++999:+1:+998E+0 ++9999:+1:+9998E+0 ++99999:+1:+99998E+0 ++999999:+1:+999998E+0 ++9999999:+1:+9999998E+0 ++99999999:+1:+99999998E+0 ++999999999:+1:+999999998E+0 ++9999999999:+1:+9999999998E+0 ++99999999999:+1:+99999999998E+0 ++10:-1:+11E+0 ++100:-1:+101E+0 ++1000:-1:+1001E+0 ++10000:-1:+10001E+0 ++100000:-1:+100001E+0 ++1000000:-1:+1000001E+0 ++10000000:-1:+10000001E+0 ++100000000:-1:+100000001E+0 ++1000000000:-1:+1000000001E+0 ++10000000000:-1:+10000000001E+0 ++123456789:+987654321:-864197532E+0 +-123456789:+987654321:-111111111E+1 +-123456789:-987654321:+864197532E+0 ++123456789:-987654321:+111111111E+1 +&fmul +abc:abc:NaN +abc:+0:NaN ++0:abc:NaN ++0:+0:+0E+0 ++0:+1:+0E+0 ++1:+0:+0E+0 ++0:-1:+0E+0 +-1:+0:+0E+0 ++123456789123456789:+0:+0E+0 ++0:+123456789123456789:+0E+0 +-1:-1:+1E+0 +-1:+1:-1E+0 ++1:-1:-1E+0 ++1:+1:+1E+0 ++2:+3:+6E+0 +-2:+3:-6E+0 ++2:-3:-6E+0 +-2:-3:+6E+0 ++111:+111:+12321E+0 ++10101:+10101:+102030201E+0 ++1001001:+1001001:+1002003002001E+0 ++100010001:+100010001:+10002000300020001E+0 ++10000100001:+10000100001:+100002000030000200001E+0 ++11111111111:+9:+99999999999E+0 ++22222222222:+9:+199999999998E+0 ++33333333333:+9:+299999999997E+0 ++44444444444:+9:+399999999996E+0 ++55555555555:+9:+499999999995E+0 ++66666666666:+9:+599999999994E+0 ++77777777777:+9:+699999999993E+0 ++88888888888:+9:+799999999992E+0 ++99999999999:+9:+899999999991E+0 +&fdiv +abc:abc:NaN +abc:+1:abc:NaN ++1:abc:NaN ++0:+0:NaN ++0:+1:+0E+0 ++1:+0:NaN ++0:-1:+0E+0 +-1:+0:NaN ++1:+1:+1E+0 +-1:-1:+1E+0 ++1:-1:-1E+0 +-1:+1:-1E+0 ++1:+2:+5E-1 ++2:+1:+2E+0 ++10:+5:+2E+0 ++100:+4:+25E+0 ++1000:+8:+125E+0 ++10000:+16:+625E+0 ++10000:-16:-625E+0 ++999999999999:+9:+111111111111E+0 ++999999999999:+99:+10101010101E+0 ++999999999999:+999:+1001001001E+0 ++999999999999:+9999:+100010001E+0 ++999999999999999:+99999:+10000100001E+0 ++1000000000:+9:+1111111111111111111111111111111111111111E-31 ++2000000000:+9:+2222222222222222222222222222222222222222E-31 ++3000000000:+9:+3333333333333333333333333333333333333333E-31 ++4000000000:+9:+4444444444444444444444444444444444444444E-31 ++5000000000:+9:+5555555555555555555555555555555555555556E-31 ++6000000000:+9:+6666666666666666666666666666666666666667E-31 ++7000000000:+9:+7777777777777777777777777777777777777778E-31 ++8000000000:+9:+8888888888888888888888888888888888888889E-31 ++9000000000:+9:+1E+9 ++35500000:+113:+3141592920353982300884955752212389380531E-34 ++71000000:+226:+3141592920353982300884955752212389380531E-34 ++106500000:+339:+3141592920353982300884955752212389380531E-34 ++1000000000:+3:+3333333333333333333333333333333333333333E-31 +$bigfloat::div_scale = 20 ++1000000000:+9:+11111111111111111111E-11 ++2000000000:+9:+22222222222222222222E-11 ++3000000000:+9:+33333333333333333333E-11 ++4000000000:+9:+44444444444444444444E-11 ++5000000000:+9:+55555555555555555556E-11 ++6000000000:+9:+66666666666666666667E-11 ++7000000000:+9:+77777777777777777778E-11 ++8000000000:+9:+88888888888888888889E-11 ++9000000000:+9:+1E+9 ++35500000:+113:+314159292035398230088E-15 ++71000000:+226:+314159292035398230088E-15 ++106500000:+339:+31415929203539823009E-14 ++1000000000:+3:+33333333333333333333E-11 +$bigfloat::div_scale = 40 +&fsqrt ++0:+0E+0 +-1:NaN +-2:NaN +-16:NaN +-123.456:NaN ++1:+1E+0 ++1.44:+12E-1 ++2:+141421356237309504880168872420969807857E-38 ++4:+2E+0 ++16:+4E+0 ++100:+1E+1 ++123.456:+1111107555549866648462149404118219234119E-38 ++15241.383936:+123456E-3 diff --git a/t/lib/bigfloatpm.t b/t/lib/bigfloatpm.t new file mode 100755 index 0000000..566038e --- /dev/null +++ b/t/lib/bigfloatpm.t @@ -0,0 +1,443 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; +} + +use Math::BigFloat; + +$test = 0; +$| = 1; +print "1..358\n"; +while () { + chop; + if (s/^&//) { + $f = $_; + } elsif (/^\$.*/) { + eval "$_;"; + } else { + ++$test; + @args = split(/:/,$_,99); + $ans = pop(@args); + $try = "\$x = new Math::BigFloat \"$args[0]\";"; + if ($f eq "fnorm"){ + $try .= "\$x+0;"; + } elsif ($f eq "fneg") { + $try .= "-\$x;"; + } elsif ($f eq "fabs") { + $try .= "abs \$x;"; + } elsif ($f eq "fround") { + $try .= "0+\$x->fround($args[1]);"; + } elsif ($f eq "ffround") { + $try .= "0+\$x->ffround($args[1]);"; + } elsif ($f eq "fsqrt") { + $try .= "0+\$x->fsqrt;"; + } else { + $try .= "\$y = new Math::BigFloat \"$args[1]\";"; + if ($f eq fcmp){ + $try .= "\$x <=> \$y;"; + }elsif ($f eq fadd){ + $try .= "\$x + \$y;"; + }elsif ($f eq fsub){ + $try .= "\$x - \$y;"; + }elsif ($f eq fmul){ + $try .= "\$x * \$y;"; + }elsif ($f eq fdiv){ + $try .= "\$x / \$y;"; + } else { warn "Unknown op"; } + } + #print ">>>",$try,"<<<\n"; + $ans1 = eval $try; + if ("$ans1" eq $ans) { #bug! + print "ok $test\n"; + } else { + print "not ok $test\n"; + print "# '$try' expected: '$ans' got: '$ans1'\n"; + } + } +} +__END__ +&fnorm +abc: + 1 a: +1bcd2: +11111b: ++1z: +-1z: +0:0. ++0:0. ++00:0. ++0 0 0:0. +000000 0000000 00000:0. +-0:0. +-0000:0. ++1:1. ++01:1. ++001:1. ++00000100000:100000. +123456789:123456789. +-1:-1. +-01:-1. +-001:-1. +-123456789:-123456789. +-00000100000:-100000. +123.456a: +123.456:123.456 +0.01:.01 +.002:.002 +-0.0003:-.0003 +-.0000000004:-.0000000004 +123456E2:12345600. +123456E-2:1234.56 +-123456E2:-12345600. +-123456E-2:-1234.56 +1e1:10. +2e-11:.00000000002 +-3e111:-3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000. +-4e-1111:-.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +&fneg +abd: ++0:0. ++1:-1. +-1:1. ++123456789:-123456789. +-123456789:123456789. ++123.456789:-123.456789 +-123456.789:123456.789 +&fabs +abc: ++0:0. ++1:1. +-1:1. ++123456789:123456789. +-123456789:123456789. ++123.456789:123.456789 +-123456.789:123456.789 +&fround +$Math::BigFloat::rnd_mode = 'trunc' ++10123456789:5:10123000000 +-10123456789:5:-10123000000 ++10123456789:9:10123456700 +-10123456789:9:-10123456700 ++101234500:6:101234000 +-101234500:6:-101234000 +$Math::BigFloat::rnd_mode = 'zero' ++20123456789:5:20123000000 +-20123456789:5:-20123000000 ++20123456789:9:20123456800 +-20123456789:9:-20123456800 ++201234500:6:201234000 +-201234500:6:-201234000 +$Math::BigFloat::rnd_mode = '+inf' ++30123456789:5:30123000000 +-30123456789:5:-30123000000 ++30123456789:9:30123456800 +-30123456789:9:-30123456800 ++301234500:6:301235000 +-301234500:6:-301234000 +$Math::BigFloat::rnd_mode = '-inf' ++40123456789:5:40123000000 +-40123456789:5:-40123000000 ++40123456789:9:40123456800 +-40123456789:9:-40123456800 ++401234500:6:401234000 +-401234500:6:-401235000 +$Math::BigFloat::rnd_mode = 'odd' ++50123456789:5:50123000000 +-50123456789:5:-50123000000 ++50123456789:9:50123456800 +-50123456789:9:-50123456800 ++501234500:6:501235000 +-501234500:6:-501235000 +$Math::BigFloat::rnd_mode = 'even' ++60123456789:5:60123000000 +-60123456789:5:-60123000000 ++60123456789:9:60123456800 +-60123456789:9:-60123456800 ++601234500:6:601234000 +-601234500:6:-601234000 +&ffround +$Math::BigFloat::rnd_mode = 'trunc' ++1.23:-1:1.2 +-1.23:-1:-1.2 ++1.27:-1:1.2 +-1.27:-1:-1.2 ++1.25:-1:1.2 +-1.25:-1:-1.2 ++1.35:-1:1.3 +-1.35:-1:-1.3 +-0.006:-1:0 +-0.006:-2:0 +-0.0065:-3:-0.006 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +$Math::BigFloat::rnd_mode = 'zero' ++2.23:-1:2.2 +-2.23:-1:-2.2 ++2.27:-1:2.3 +-2.27:-1:-2.3 ++2.25:-1:2.2 +-2.25:-1:-2.2 ++2.35:-1:2.3 +-2.35:-1:-2.3 +-0.0065:-1:0 +-0.0065:-2:-0.01 +-0.0065:-3:-0.006 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +$Math::BigFloat::rnd_mode = '+inf' ++3.23:-1:3.2 +-3.23:-1:-3.2 ++3.27:-1:3.3 +-3.27:-1:-3.3 ++3.25:-1:3.3 +-3.25:-1:-3.2 ++3.35:-1:3.4 +-3.35:-1:-3.3 +-0.0065:-1:0 +-0.0065:-2:-0.01 +-0.0065:-3:-0.006 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +$Math::BigFloat::rnd_mode = '-inf' ++4.23:-1:4.2 +-4.23:-1:-4.2 ++4.27:-1:4.3 +-4.27:-1:-4.3 ++4.25:-1:4.2 +-4.25:-1:-4.3 ++4.35:-1:4.3 +-4.35:-1:-4.4 +-0.0065:-1:0 +-0.0065:-2:-0.01 +-0.0065:-3:-0.007 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +$Math::BigFloat::rnd_mode = 'odd' ++5.23:-1:5.2 +-5.23:-1:-5.2 ++5.27:-1:5.3 +-5.27:-1:-5.3 ++5.25:-1:5.3 +-5.25:-1:-5.3 ++5.35:-1:5.3 +-5.35:-1:-5.3 +-0.0065:-1:0 +-0.0065:-2:-0.01 +-0.0065:-3:-0.007 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +$Math::BigFloat::rnd_mode = 'even' ++6.23:-1:6.2 +-6.23:-1:-6.2 ++6.27:-1:6.3 +-6.27:-1:-6.3 ++6.25:-1:6.2 +-6.25:-1:-6.2 ++6.35:-1:6.4 +-6.35:-1:-6.4 +-0.0065:-1:0 +-0.0065:-2:-0.01 +-0.0065:-3:-0.006 +-0.0065:-4:-0.0065 +-0.0065:-5:-0.0065 +&fcmp +abc:abc: +abc:+0: ++0:abc: ++0:+0:0 +-1:+0:-1 ++0:-1:1 ++1:+0:1 ++0:+1:-1 +-1:+1:-1 ++1:-1:1 +-1:-1:0 ++1:+1:0 ++123:+123:0 ++123:+12:1 ++12:+123:-1 +-123:-123:0 +-123:-12:-1 +-12:-123:1 ++123:+124:-1 ++124:+123:1 +-123:-124:1 +-124:-123:-1 +&fadd +abc:abc: +abc:+0: ++0:abc: ++0:+0:0. ++1:+0:1. ++0:+1:1. ++1:+1:2. +-1:+0:-1. ++0:-1:-1. +-1:-1:-2. +-1:+1:0. ++1:-1:0. ++9:+1:10. ++99:+1:100. ++999:+1:1000. ++9999:+1:10000. ++99999:+1:100000. ++999999:+1:1000000. ++9999999:+1:10000000. ++99999999:+1:100000000. ++999999999:+1:1000000000. ++9999999999:+1:10000000000. ++99999999999:+1:100000000000. ++10:-1:9. ++100:-1:99. ++1000:-1:999. ++10000:-1:9999. ++100000:-1:99999. ++1000000:-1:999999. ++10000000:-1:9999999. ++100000000:-1:99999999. ++1000000000:-1:999999999. ++10000000000:-1:9999999999. ++123456789:+987654321:1111111110. +-123456789:+987654321:864197532. +-123456789:-987654321:-1111111110. ++123456789:-987654321:-864197532. +&fsub +abc:abc: +abc:+0: ++0:abc: ++0:+0:0. ++1:+0:1. ++0:+1:-1. ++1:+1:0. +-1:+0:-1. ++0:-1:1. +-1:-1:0. +-1:+1:-2. ++1:-1:2. ++9:+1:8. ++99:+1:98. ++999:+1:998. ++9999:+1:9998. ++99999:+1:99998. ++999999:+1:999998. ++9999999:+1:9999998. ++99999999:+1:99999998. ++999999999:+1:999999998. ++9999999999:+1:9999999998. ++99999999999:+1:99999999998. ++10:-1:11. ++100:-1:101. ++1000:-1:1001. ++10000:-1:10001. ++100000:-1:100001. ++1000000:-1:1000001. ++10000000:-1:10000001. ++100000000:-1:100000001. ++1000000000:-1:1000000001. ++10000000000:-1:10000000001. ++123456789:+987654321:-864197532. +-123456789:+987654321:-1111111110. +-123456789:-987654321:864197532. ++123456789:-987654321:1111111110. +&fmul +abc:abc: +abc:+0: ++0:abc: ++0:+0:0. ++0:+1:0. ++1:+0:0. ++0:-1:0. +-1:+0:0. ++123456789123456789:+0:0. ++0:+123456789123456789:0. +-1:-1:1. +-1:+1:-1. ++1:-1:-1. ++1:+1:1. ++2:+3:6. +-2:+3:-6. ++2:-3:-6. +-2:-3:6. ++111:+111:12321. ++10101:+10101:102030201. ++1001001:+1001001:1002003002001. ++100010001:+100010001:10002000300020001. ++10000100001:+10000100001:100002000030000200001. ++11111111111:+9:99999999999. ++22222222222:+9:199999999998. ++33333333333:+9:299999999997. ++44444444444:+9:399999999996. ++55555555555:+9:499999999995. ++66666666666:+9:599999999994. ++77777777777:+9:699999999993. ++88888888888:+9:799999999992. ++99999999999:+9:899999999991. +&fdiv +abc:abc: +abc:+1:abc: ++1:abc: ++0:+0: ++0:+1:0. ++1:+0: ++0:-1:0. +-1:+0: ++1:+1:1. +-1:-1:1. ++1:-1:-1. +-1:+1:-1. ++1:+2:.5 ++2:+1:2. ++10:+5:2. ++100:+4:25. ++1000:+8:125. ++10000:+16:625. ++10000:-16:-625. ++999999999999:+9:111111111111. ++999999999999:+99:10101010101. ++999999999999:+999:1001001001. ++999999999999:+9999:100010001. ++999999999999999:+99999:10000100001. ++1000000000:+9:111111111.1111111111111111111111111111111 ++2000000000:+9:222222222.2222222222222222222222222222222 ++3000000000:+9:333333333.3333333333333333333333333333333 ++4000000000:+9:444444444.4444444444444444444444444444444 ++5000000000:+9:555555555.5555555555555555555555555555556 ++6000000000:+9:666666666.6666666666666666666666666666667 ++7000000000:+9:777777777.7777777777777777777777777777778 ++8000000000:+9:888888888.8888888888888888888888888888889 ++9000000000:+9:1000000000. ++35500000:+113:314159.2920353982300884955752212389380531 ++71000000:+226:314159.2920353982300884955752212389380531 ++106500000:+339:314159.2920353982300884955752212389380531 ++1000000000:+3:333333333.3333333333333333333333333333333 +$Math::BigFloat::div_scale = 20 ++1000000000:+9:111111111.11111111111 ++2000000000:+9:222222222.22222222222 ++3000000000:+9:333333333.33333333333 ++4000000000:+9:444444444.44444444444 ++5000000000:+9:555555555.55555555556 ++6000000000:+9:666666666.66666666667 ++7000000000:+9:777777777.77777777778 ++8000000000:+9:888888888.88888888889 ++9000000000:+9:1000000000. ++35500000:+113:314159.292035398230088 ++71000000:+226:314159.292035398230088 ++106500000:+339:314159.29203539823009 ++1000000000:+3:333333333.33333333333 +$Math::BigFloat::div_scale = 40 +&fsqrt ++0:0 +-1:NaN +-2:NaN +-16:NaN +-123.456:NaN ++1:1. ++1.44:1.2 ++2:1.41421356237309504880168872420969807857 ++4:2. ++16:4. ++100:10. ++123.456:11.11107555549866648462149404118219234119 ++15241.383936:123.456 diff --git a/t/lib/bigintpm.t b/t/lib/bigintpm.t index e6c775f..62eea74 100755 --- a/t/lib/bigintpm.t +++ b/t/lib/bigintpm.t @@ -93,29 +93,29 @@ abc:NaN +123456789:+123456789 -123456789:+123456789 &bcmp -abc:abc:NaN -abc:+0:NaN -+0:abc:NaN -+0:+0:+0 +abc:abc: +abc:+0: ++0:abc: ++0:+0:0 -1:+0:-1 -+0:-1:+1 -+1:+0:+1 ++0:-1:1 ++1:+0:1 +0:+1:-1 -1:+1:-1 -+1:-1:+1 --1:-1:+0 -+1:+1:+0 -+123:+123:+0 -+123:+12:+1 ++1:-1:1 +-1:-1:0 ++1:+1:0 ++123:+123:0 ++123:+12:1 +12:+123:-1 --123:-123:+0 +-123:-123:0 -123:-12:-1 --12:-123:+1 +-12:-123:1 +123:+124:-1 -+124:+123:+1 --123:-124:+1 ++124:+123:1 +-123:-124:1 -124:-123:-1 -+100:+5:+1 ++100:+5:1 &badd abc:abc:NaN abc:+0:NaN