summaryrefslogtreecommitdiff
path: root/lib/Math/BigInt
diff options
context:
space:
mode:
authorTels <nospam-abuse@bloodgate.com>2003-12-12 19:47:43 +0100
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2003-12-12 22:43:11 +0000
commit8df1e0a2b21ea34567b1f903327ae2a11bb9b86e (patch)
tree3fe9e6dfea8b2de78a5d79f4ccad0fbdfa704d8a /lib/Math/BigInt
parent087c4f22370f16639ef0e86293c159a934ea228c (diff)
downloadperl-8df1e0a2b21ea34567b1f903327ae2a11bb9b86e.tar.gz
Math::BigInt v1.67 released
Message-Id: <200312121847.49039@bloodgate.com> p4raw-id: //depot/perl@21882
Diffstat (limited to 'lib/Math/BigInt')
-rw-r--r--lib/Math/BigInt/Calc.pm38
-rw-r--r--lib/Math/BigInt/t/bare_mbi.t2
-rw-r--r--lib/Math/BigInt/t/bigintpm.inc16
-rwxr-xr-xlib/Math/BigInt/t/bigintpm.t2
-rw-r--r--lib/Math/BigInt/t/downgrade.t8
-rw-r--r--lib/Math/BigInt/t/fallback.t4
-rwxr-xr-xlib/Math/BigInt/t/sub_mbi.t2
7 files changed, 56 insertions, 16 deletions
diff --git a/lib/Math/BigInt/Calc.pm b/lib/Math/BigInt/Calc.pm
index 6db1a62bd0..02770e22e1 100644
--- a/lib/Math/BigInt/Calc.pm
+++ b/lib/Math/BigInt/Calc.pm
@@ -1351,38 +1351,48 @@ sub _log_int
if ($cmp == 0)
{
splice (@$x,1); $x->[0] = 1;
- return $x;
+ return ($x,1)
}
# X < BASE
if ($cmp < 0)
{
splice (@$x,1); $x->[0] = 0;
- return $x;
+ return ($x,undef);
}
# this trial multiplication is very fast, even for large counts (like for
# 2 ** 1024, since this still requires only 1024 very fast steps
# (multiplication of a large number by a very small number is very fast))
my $x_org = _copy($c,$x); # preserve x
- splice(@$x,1); $x->[0] = 0; # keep ref to $x
+ splice(@$x,1); $x->[0] = 1; # keep ref to $x
+
+ # simple loop that increments $x by two in each step, possible overstepping
+ # the real result by one
# use a loop that keeps $x as scalar as long as possible (this is faster)
- my $trial = _copy($c,$base); my $count = 0; my $a;
- while (($a = _acmp($x,$trial,$x_org) <= 0) && $count < $BASE)
+ my $trial = _copy($c,$base); my $a;
+ my $base_mul = _mul($c, _copy($c,$base), $base);
+
+ while (($a = _acmp($x,$trial,$x_org)) < 0)
{
- _mul($c,$trial,$base); $count++;
+ _mul($c,$trial,$base_mul); _add($c, $x, [2]);
}
- if ($a <= 0)
+
+ my $exact = 1;
+ if ($a > 0)
{
- # not done yet?
- $x->[0] = $count;
- while (_acmp($x,$trial,$x_org) <= 0)
+ # overstepped the result
+ _dec($c, $x);
+ _div($c,$trial,$base);
+ $a = _acmp($x,$trial,$x_org);
+ if ($a > 0)
{
- _mul($c,$trial,$base); _inc($c,$x);
+ _dec($c, $x);
}
+ $exact = 0 if $a != 0;
}
- $x; # return result
+ ($x,$exact); # return result
}
# for debugging:
@@ -1978,6 +1988,10 @@ slow) fallback routines to emulate these:
_modpow return modulus of power ($x ** $y) % $z
_log_int(X,N) calculate integer log() of X in base N
X >= 0, N >= 0 (return undef for NaN)
+ returns (RESULT, EXACT) where EXACT is:
+ 1 : result is exactly RESULT
+ 0 : result was truncated to RESULT
+ undef : unknown whether result is exactly RESULT
Input strings come in as unsigned but with prefix (i.e. as '123', '0xabc'
or '0b1101').
diff --git a/lib/Math/BigInt/t/bare_mbi.t b/lib/Math/BigInt/t/bare_mbi.t
index 6bcc6bd266..0af4c42742 100644
--- a/lib/Math/BigInt/t/bare_mbi.t
+++ b/lib/Math/BigInt/t/bare_mbi.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2728;
+ plan tests => 2760;
}
use Math::BigInt lib => 'BareCalc';
diff --git a/lib/Math/BigInt/t/bigintpm.inc b/lib/Math/BigInt/t/bigintpm.inc
index 332f575211..db52553c92 100644
--- a/lib/Math/BigInt/t/bigintpm.inc
+++ b/lib/Math/BigInt/t/bigintpm.inc
@@ -718,6 +718,22 @@ inf:inf:NaN
15625:5:6
15626:5:6
15624:5:5
+1000:10:3
+10000:10:4
+100000:10:5
+1000000:10:6
+10000000:10:7
+100000000:10:8
+8916100448256:12:12
+8916100448257:12:12
+8916100448255:12:11
+2251799813685248:8:17
+72057594037927936:2:56
+144115188075855872:2:57
+288230376151711744:2:58
+576460752303423488:2:59
+4096:2:12
+1329227995784915872903807060280344576:2:120
# $x == $base => result 1
3:3:1
# $x < $base => result 0 ($base ** 0 <= $x)
diff --git a/lib/Math/BigInt/t/bigintpm.t b/lib/Math/BigInt/t/bigintpm.t
index b541aae606..d4e0772d7d 100755
--- a/lib/Math/BigInt/t/bigintpm.t
+++ b/lib/Math/BigInt/t/bigintpm.t
@@ -10,7 +10,7 @@ BEGIN
my $location = $0; $location =~ s/bigintpm.t//;
unshift @INC, $location; # to locate the testing files
chdir 't' if -d 't';
- plan tests => 2728;
+ plan tests => 2760;
}
use Math::BigInt;
diff --git a/lib/Math/BigInt/t/downgrade.t b/lib/Math/BigInt/t/downgrade.t
index 0208a56bc3..25d672c50f 100644
--- a/lib/Math/BigInt/t/downgrade.t
+++ b/lib/Math/BigInt/t/downgrade.t
@@ -10,7 +10,7 @@ BEGIN
my $location = $0; $location =~ s/downgrade.t//;
unshift @INC, $location; # to locate the testing files
chdir 't' if -d 't';
- plan tests => 12;
+ plan tests => 15;
}
use Math::BigInt upgrade => 'Math::BigFloat';
@@ -36,6 +36,12 @@ ok (ref(Math::BigFloat->new('10')),'Math::BigInt');
ok (ref(Math::BigFloat->new('-10')),'Math::BigInt');
ok (ref(Math::BigFloat->new('-10.0E1')),'Math::BigInt');
+# bug until v1.67:
+ok (Math::BigFloat->new('0.2E0'), '0.2');
+ok (Math::BigFloat->new('0.2E1'), '2');
+# until v1.67 resulted in 200:
+ok (Math::BigFloat->new('0.2E2'), '20');
+
# disable, otherwise it screws calculations
Math::BigFloat->upgrade(undef);
ok (Math::BigFloat->upgrade()||'','');
diff --git a/lib/Math/BigInt/t/fallback.t b/lib/Math/BigInt/t/fallback.t
index c09a201a5c..e348d9240d 100644
--- a/lib/Math/BigInt/t/fallback.t
+++ b/lib/Math/BigInt/t/fallback.t
@@ -31,6 +31,10 @@ BEGIN
plan tests => 8;
}
+# The tests below test that cos(BigInt) = cos(Scalar) which is DWIM, but not
+# exactly right, ideally cos(BigInt) should truncate to int() and cos(BigFLoat)
+# should calculate the result to X digits accuracy. For now, this is better
+# than die()ing...
use Math::BigInt;
use Math::BigFloat;
diff --git a/lib/Math/BigInt/t/sub_mbi.t b/lib/Math/BigInt/t/sub_mbi.t
index 65c6d0b25f..3b3c6e645e 100755
--- a/lib/Math/BigInt/t/sub_mbi.t
+++ b/lib/Math/BigInt/t/sub_mbi.t
@@ -26,7 +26,7 @@ BEGIN
}
print "# INC = @INC\n";
- plan tests => 2728
+ plan tests => 2760
+ 5; # +5 own tests
}