X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbigint.pl;h=bfd2efa88c8a1f54a915174abf3ba22af0610c34;hb=1b33cabaaf2fbe2e84c6a13a9b0a7fce45959c4f;hp=a2a0da977e4a0e29c280c67b29f3efea78da4801;hpb=79072805bf63abe5b5978b5928ab00d360ea3e7f;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/bigint.pl b/lib/bigint.pl index a2a0da9..bfd2efa 100644 --- a/lib/bigint.pl +++ b/lib/bigint.pl @@ -33,10 +33,14 @@ package bigint; # bgcd(BINT,BINT) return BINT greatest common divisor # bnorm(BINT) return BINT normalization # + +$zero = 0; + # normalize string form of number. Strip leading zeros. Strip any # white space and add a sign, if missing. # Strings that are not numbers result the value 'NaN'. + sub main'bnorm { #(num_str) return num_str local($_) = @_; s/\s+//g; # strip white space @@ -99,13 +103,23 @@ sub main'bcmp { #(num_str, num_str) return cond_code sub cmp { # post-normalized compare for internal use local($cx, $cy) = @_; - $cx cmp $cy - && - ( - ord($cy) <=> ord($cx) - || - ($cx cmp ',') * (length($cy) <=> length($cx) || $cy cmp $cx) - ); + return 0 if ($cx eq $cy); + + local($sx, $sy) = (substr($cx, 0, 1), substr($cy, 0, 1)); + local($ld); + + if ($sx eq '+') { + return 1 if ($sy eq '-' || $cy eq '+0'); + $ld = length($cx) - length($cy); + return $ld if ($ld); + return $cx cmp $cy; + } else { # $sx eq '-' + return -1 if ($sy eq '+'); + $ld = length($cy) - length($cx); + return $ld if ($ld); + return $cy cmp $cx; + } + } sub main'badd { #(num_str, num_str) return num_str @@ -154,11 +168,11 @@ sub add { #(int_num_array, int_num_array) return int_num_array $car = 0; for $x (@x) { last unless @y || $car; - $x -= 1e5 if $car = (($x += shift(@y) + $car) >= 1e5); + $x -= 1e5 if $car = (($x += shift(@y) + $car) >= 1e5) ? 1 : 0; } for $y (@y) { last unless $car; - $y -= 1e5 if $car = (($y += $car) >= 1e5); + $y -= 1e5 if $car = (($y += $car) >= 1e5) ? 1 : 0; } (@x, @y, $car); } @@ -228,9 +242,9 @@ sub main'bdiv { #(dividend: num_str, divisor: num_str) return num_str else { push(@x, 0); } - @q = (); ($v2,$v1) = @y[$#y-1,$#y]; + @q = (); ($v2,$v1) = @y[-2,-1]; while ($#x > $#y) { - ($u2,$u1,$u0) = @x[($#x-2)..$#x]; + ($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) { @@ -263,7 +277,7 @@ sub main'bdiv { #(dividend: num_str, divisor: num_str) return num_str else { @d = @x; } - (&external($sr, @q), &external($srem, @d, 0)); + (&external($sr, @q), &external($srem, @d, $zero)); } else { &external($sr, @q); }