This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[inseparable changes from match from perl-5.003_99 to perl-5.003_99a]
[perl5.git] / lib / bigint.pl
index a2a0da9..bfd2efa 100644 (file)
@@ -33,10 +33,14 @@ package bigint;
 #   bgcd(BINT,BINT) return BINT         greatest common divisor
 #   bnorm(BINT) return BINT             normalization
 #
+
+$zero = 0;
+
 \f
 # 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);
     }