# 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
sub main'bneg { #(num_str) return num_str
local($_) = &'bnorm(@_);
vec($_,0,8) ^= ord('+') ^ ord('-') unless $_ eq '+0';
- s/^H/N/;
+ s/^./N/ unless /^[-+]/; # works both in ASCII and EBCDIC
$_;
}
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
$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);
}
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) {
else {
@d = @x;
}
- (&external($sr, @q), &external($srem, @d, 0));
+ (&external($sr, @q), &external($srem, @d, $zero));
} else {
&external($sr, @q);
}