X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMath%2FBigInt.pm;h=ef4af613c31fcd6fccc6f982e626d6f8fda7ccc1;hb=e3c7ef20866011e0e98de5b78863094f34fd2bd6;hp=a4d8b6bd182aba421005af7595a87a47cf5f1b8c;hpb=1e2e1ae8d60a2653b0297f8d75f9d4fe5abfc82b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/Math/BigInt.pm b/lib/Math/BigInt.pm index a4d8b6b..ef4af61 100644 --- a/lib/Math/BigInt.pm +++ b/lib/Math/BigInt.pm @@ -36,6 +36,12 @@ sub stringify { "${$_[0]}" } sub numify { 0 + "${$_[0]}" } # Not needed, additional overhead # comparing to direct compilation based on # stringify +sub import { + shift; + return unless @_; + die "unknown import: @_" unless @_ == 1 and $_[0] eq ':constant'; + overload::constant integer => sub {Math::BigInt->new(shift)}; +} $zero = 0; @@ -76,8 +82,8 @@ sub external { #(int_num_array) return num_str # Negate input value. sub bneg { #(num_str) return num_str local($_) = &bnorm(@_); - vec($_,0,8) ^= ord('+') ^ ord('-') unless $_ eq '+0'; - s/^H/N/; + return $_ if $_ eq '+0' or $_ eq 'NaN'; + vec($_,0,8) ^= ord('+') ^ ord('-'); $_; } @@ -100,7 +106,7 @@ sub bcmp { #(num_str, num_str) return cond_code } elsif ($y eq 'NaN') { undef; } else { - &cmp($x,$y); + &cmp($x,$y) <=> 0; } } @@ -171,11 +177,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 += (@y ? shift(@y) : 0) + $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); } @@ -185,8 +191,8 @@ sub sub { #(int_num_array, int_num_array) return int_num_array local(*sx, *sy) = @_; $bar = 0; for $sx (@sx) { - last unless @y || $bar; - $sx += 1e5 if $bar = (($sx -= shift(@sy) + $bar) < 0); + last unless @sy || $bar; + $sx += 1e5 if $bar = (($sx -= (@sy ? shift(@sy) : 0) + $bar) < 0); } @sx; } @@ -214,7 +220,7 @@ sub mul { #(*int_num_array, *int_num_array) return int_num_array for $x (@x) { ($car, $cty) = (0, $[); for $y (@y) { - $prod = $x * $y + $prod[$cty] + $car; + $prod = $x * $y + ($prod[$cty] || 0) + $car; $prod[$cty++] = $prod - ($car = int($prod * 1e-5)) * 1e5; } @@ -384,6 +390,19 @@ are not numbers, as well as the result of dividing by zero. '1 23 456 7890' canonical value '+1234567890' +=head1 Autocreating constants + +After C all the integer decimal constants +in the given scope are converted to C. This conversion +happens at compile time. + +In particular + + perl -MMath::BigInt=:constant -e 'print 2**100' + +print the integer value of C<2**100>. Note that without convertion of +constants the expression 2**100 will be calculatted as floating point number. + =head1 BUGS The current version of this module is a preliminary version of the