diff options
author | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2016-12-03 07:23:23 +0000 |
---|---|---|
committer | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2016-12-03 07:23:23 +0000 |
commit | d239a8c7513e81cdb8d891f44da53ca5adcebeae (patch) | |
tree | e78e979ffb0343db833b2e5d7ed9b934b8fae19b /cpan/Math-BigInt-FastCalc | |
parent | 54b49d9685a18180ada6dbdb5bb02cb8459e6bd7 (diff) | |
download | perl-d239a8c7513e81cdb8d891f44da53ca5adcebeae.tar.gz |
Update Math-BigInt-FastCalc to CPAN version 0.5002
[DELTA]
2016-11-23 v0.5002 pjacklam
* Sync test files with Math-BigInt-1.999801. Add t/biglog.t and t/bigroot.t
since these are included in the test suite for the other backend libraries
(GMP and Pari).
2016-11-17 v0.5001 pjacklam
* Avoid 'use parent' to retain compatibility with old Perls.
* Fix incorrect version numbers in the CHANGES file.
* Trim whitespace.
2016-11-15 v0.5000 pjacklam
* Sync test files with Math-BigInt-1.999800.
* Math::BigInt::FastCalc is now a subclass of Math::BigInt::Calc, so remove
aliases like *Math::BigInt::FastCalc::_xxx = \&Math::BigInt::Calc::_xxx.
* Use OO-calls rather than function calls.
* Fix documentation error in Math::BigInt::FastCalc
Diffstat (limited to 'cpan/Math-BigInt-FastCalc')
-rw-r--r-- | cpan/Math-BigInt-FastCalc/FastCalc.xs | 13 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm | 59 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/bigintfc.t | 25 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/biglog.t | 244 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/bigroot.t | 53 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/bootstrap.t | 1 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/leak.t | 5 | ||||
-rw-r--r-- | cpan/Math-BigInt-FastCalc/t/mbi_rand.t | 123 |
8 files changed, 428 insertions, 95 deletions
diff --git a/cpan/Math-BigInt-FastCalc/FastCalc.xs b/cpan/Math-BigInt-FastCalc/FastCalc.xs index eb228e4ca5..f8bb3140e8 100644 --- a/cpan/Math-BigInt-FastCalc/FastCalc.xs +++ b/cpan/Math-BigInt-FastCalc/FastCalc.xs @@ -152,7 +152,7 @@ __strip_zeros(x) elems = av_len(a); /* number of elems in array */ ST(0) = x; /* we return x */ if (elems == -1) - { + { av_push (a, newSViv(0)); /* correct empty arrays */ XSRETURN(1); } @@ -210,13 +210,13 @@ _dec(class,x) } sv_setnv (temp, MAX); /* overflow, so set this to $MAX */ index++; - } + } /* do have more than one element? */ /* (more than one because [0] should be kept as single-element) */ if (elems > 0) { temp = *av_fetch(a, elems, 0); /* fetch last element */ - if (SvIV(temp) == 0) /* did last elem overflow? */ + if (SvIV(temp) == 0) /* did last elem overflow? */ { av_pop(a); /* yes, so shrink array */ /* aka remove leading zeros */ @@ -254,7 +254,7 @@ _inc(class,x) } sv_setiv (temp, 0); /* overflow, so set this elem to 0 */ index++; - } + } temp = *av_fetch(a, elems, 0); /* fetch last element */ if (SvIV(temp) == 0) /* did last elem overflow? */ { @@ -394,10 +394,10 @@ _acmp(class, cx, cy); diff_nv = SvNV(tempx) - SvNV(tempy); if (diff_nv != 0) { - break; + break; } elemsx--; - } + } if (diff_nv > 0) { RETURN_MORTAL_INT(1); @@ -407,4 +407,3 @@ _acmp(class, cx, cy); RETURN_MORTAL_INT(-1); } ST(0) = sv_2mortal(newSViv(0)); /* X and Y are equal */ - diff --git a/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm b/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm index 09409b883f..6520d721a9 100644 --- a/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm +++ b/cpan/Math-BigInt-FastCalc/lib/Math/BigInt/FastCalc.pm @@ -4,9 +4,11 @@ use 5.006; use strict; use warnings; -use Math::BigInt::Calc 1.999706; +use Math::BigInt::Calc '1.999801'; -our $VERSION = '0.42'; +our @ISA = qw< Math::BigInt::Calc >; + +our $VERSION = '0.5002'; ############################################################################## # global constants, flags and accessory @@ -16,26 +18,8 @@ sub api_version () { 2; } # use Calc to override the methods that we do not provide in XS -for my $method (qw/ - str num - add sub mul div - rsft lsft - mod modpow modinv - gcd - pow root sqrt log_int fac nok - digit check - from_hex from_bin from_oct as_hex as_bin as_oct - zeros base_len - xor or and - alen 1ex - /) - { - no strict 'refs'; - *{'Math::BigInt::FastCalc::_' . $method} = \&{'Math::BigInt::Calc::_' . $method}; - } - require XSLoader; -XSLoader::load(__PACKAGE__, $VERSION, Math::BigInt::Calc::_base_len()); +XSLoader::load(__PACKAGE__, $VERSION, Math::BigInt::Calc->_base_len()); ############################################################################## ############################################################################## @@ -52,12 +36,23 @@ Math::BigInt::FastCalc - Math::BigInt::Calc with some XS for more speed =head1 SYNOPSIS + # to use it with Math::BigInt + use Math::BigInt lib => 'FastCalc'; + + # to use it with Math::BigFloat + use Math::BigFloat lib => 'FastCalc'; + + # to use it with Math::BigRat + use Math::BigRat lib => 'FastCalc'; + +=head1 DESCRIPTION + +Math::BigInt::FastCalc inherits from Math::BigInt::Calc. + Provides support for big integer calculations. Not intended to be used by other modules. Other modules which sport the same functions can also be used to support Math::BigInt, like L<Math::BigInt::GMP> or L<Math::BigInt::Pari>. -=head1 DESCRIPTION - In order to allow for multiple big integer libraries, Math::BigInt was rewritten to use library modules for core math routines. Any module which follows the same API as this can be used instead by using the following: @@ -69,13 +64,10 @@ version like 'Pari'. To use this library: use Math::BigInt lib => 'FastCalc'; -Note that from L<Math::BigInt> v1.76 onwards, FastCalc will be loaded -automatically, if possible. - =head1 STORAGE -FastCalc works exactly like Calc, in stores the numbers in decimal form, -chopped into parts. +Math::BigInt::FastCalc works exactly like Math::BigInt::Calc. Numbers are +stored in decimal form chopped into parts. =head1 METHODS @@ -161,11 +153,16 @@ Separated from BigInt and shaped API with the help of John Peacock. Fixed, sped-up and enhanced by Tels http://bloodgate.com 2001-2003. Further streamlining (api_version 1 etc.) by Tels 2004-2007. -Bug-fixing by Peter John Acklam E<lt>pjacklam@online.noE<gt> 2010-2015. +Bug-fixing by Peter John Acklam E<lt>pjacklam@online.noE<gt> 2010-2016. =head1 SEE ALSO -L<Math::BigInt>, L<Math::BigFloat>, and the other backends -L<Math::BigInt::Calc>, L<Math::BigInt::GMP>, and L<Math::BigInt::Pari>. +L<Math::BigInt::Lib> for a description of the API. + +Alternative libraries L<Math::BigInt::Calc>, L<Math::BigInt::GMP>, and +L<Math::BigInt::Pari>. + +Some of the modules that use these libraries L<Math::BigInt>, +L<Math::BigFloat>, and L<Math::BigRat>. =cut diff --git a/cpan/Math-BigInt-FastCalc/t/bigintfc.t b/cpan/Math-BigInt-FastCalc/t/bigintfc.t index c8751ad81b..a3dd4a8d37 100644 --- a/cpan/Math-BigInt-FastCalc/t/bigintfc.t +++ b/cpan/Math-BigInt-FastCalc/t/bigintfc.t @@ -148,17 +148,17 @@ $x = $C->_new("123000"); is ($C->_zeros($x),3); $x = $C->_new("0"); is ($C->_zeros($x),0); # _lsft, _rsft -$x = $C->_new("10"); $y = $C->_new("3"); +$x = $C->_new("10"); $y = $C->_new("3"); is ($C->_str($C->_lsft($x,$y,10)),10000); -$x = $C->_new("20"); $y = $C->_new("3"); +$x = $C->_new("20"); $y = $C->_new("3"); is ($C->_str($C->_lsft($x,$y,10)),20000); $x = $C->_new("128"); $y = $C->_new("4"); is ($C->_str($C->_lsft($x,$y,2)), 128 << 4); -$x = $C->_new("1000"); $y = $C->_new("3"); +$x = $C->_new("1000"); $y = $C->_new("3"); is ($C->_str($C->_rsft($x,$y,10)),1); -$x = $C->_new("20000"); $y = $C->_new("3"); +$x = $C->_new("20000"); $y = $C->_new("3"); is ($C->_str($C->_rsft($x,$y,10)),20); $x = $C->_new("256"); $y = $C->_new("4"); is ($C->_str($C->_rsft($x,$y,2)),256 >> 4); @@ -211,13 +211,13 @@ $x = $C->_new("3333"); $y = $C->_new("1111"); is ($C->_str(scalar $C->_div($x,$y)),3); $x = $C->_new("33333"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y); is ($C->_str($x),30); is ($C->_str($y),3); -$x = $C->_new("123"); $y = $C->_new("1111"); +$x = $C->_new("123"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y); is ($C->_str($x),0); is ($C->_str($y),123); # _num foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { - $x = $C->_new("$_"); + $x = $C->_new("$_"); is (ref($x),'ARRAY'); is ($C->_str($x),"$_"); $x = $C->_num($x); is (ref($x),''); is ($x,$_); } @@ -242,7 +242,7 @@ is ($C->_str($C->_pow($x,$n)), 1); $x = $C->_new("5"); $n = $C->_new("1"); # x ** 1 => x is ($C->_str($C->_pow($x,$n)), 5); -$x = $C->_new("81"); $n = $C->_new("3"); # 81 ** 3 == 531441 +$x = $C->_new("81"); $n = $C->_new("3"); # 81 ** 3 == 531441 is ($C->_str($C->_pow($x,$n)),81 ** 3); is ($C->_str($C->_root($x,$n)),81); @@ -254,7 +254,7 @@ is ($C->_str($C->_pow($x,$n)),'150094635296999121'); # 531441 ** 3 == is ($C->_str($C->_root($x,$n)),'531441'); is ($C->_str($C->_root($x,$n)),'81'); -$x = $C->_new("81"); $n = $C->_new("14"); +$x = $C->_new("81"); $n = $C->_new("14"); is ($C->_str($C->_pow($x,$n)),'523347633027360537213511521'); is ($C->_str($C->_root($x,$n)),'81'); @@ -274,7 +274,7 @@ for my $i (2 .. 9) my $rc = '9' x ($i-1). '8' . '0' x ($i-1) . '1'; print "# _pow( ", '9' x $i, ", 2) \n" unless is ($C->_str($C->_pow($x,$n)),$rc); - + if ($i <= 7) { $x = '9' x $i; $x = $C->_new($x); @@ -333,11 +333,7 @@ foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) $x = $C->_new("1000"); $C->_inc($x); is ($C->_str($x),'1001'); $C->_dec($x); is ($C->_str($x),'1000'); -my $BL; -{ - no strict 'refs'; - $BL = &{"$C"."::_base_len"}(); -} +my $BL = $C -> _base_len(); $x = '1' . '0' x $BL; $z = '1' . '0' x ($BL-1); $z .= '1'; @@ -427,4 +423,3 @@ is ($C->_check(123),'123 is not a reference'); # done 1; - diff --git a/cpan/Math-BigInt-FastCalc/t/biglog.t b/cpan/Math-BigInt-FastCalc/t/biglog.t new file mode 100644 index 0000000000..6c227e8e8a --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/t/biglog.t @@ -0,0 +1,244 @@ +#!perl + +# Test blog function (and bpow, since it uses blog), as well as bexp(). + +# It is too slow to be simple included in bigfltpm.inc, where it would get +# executed 3 times. One time would be under Math::BigInt::BareCalc, which +# shouldn't make any difference since there is no CALC->_log() function, and +# one time under a subclass, which *should* work. + +# But it is better to test the numerical functionality, instead of not testing +# it at all (which did lead to wrong answers for 0 < $x < 1 in blog() in +# versions up to v1.63, and for bsqrt($x) when $x << 1 for instance). + +use strict; +use warnings; + +use Test::More tests => 73; + +use Math::BigFloat only => 'FastCalc'; +use Math::BigInt; + +my $class = "Math::BigInt"; + +############################################################################### +# test $n->blog() in Math::BigInt (broken until 1.80) + +is($class->new(2)->blog(), '0', "$class->new(2)->blog()"); +is($class->new(288)->blog(), '5', "$class->new(288)->blog()"); +is($class->new(2000)->blog(), '7', "$class->new(2000)->blog()"); + +############################################################################### +# test $n->bexp() in Math::BigInt + +is($class->new(1)->bexp(), '2', "$class->new(1)->bexp()"); +is($class->new(2)->bexp(), '7', "$class->new(2)->bexp()"); +is($class->new(3)->bexp(), '20', "$class->new(3)->bexp()"); + +############################################################################### +############################################################################### +# Math::BigFloat tests + +############################################################################### +# test $n->blog(undef, N) where N > 67 (broken until 1.82) + +$class = "Math::BigFloat"; + +# These tests can take quite a while, but are necessary. Maybe protect them +# with some alarm()? + +# this triggers the calculation and caching of ln(2): +is($class->new(5)->blog(undef, 71), + '1.6094379124341003746007593332261876395256013542685177219126478914741790', + "$class->new(5)->blog(undef, 71)"); + +# if the cache was correct, we should get this result, fast: +is($class->new(2)->blog(undef, 71), + '0.69314718055994530941723212145817656807550013436025525412068000949339362', + "$class->new(2)->blog(undef, 71)"); + +is($class->new(11)->blog(undef, 71), + '2.3978952727983705440619435779651292998217068539374171752185677091305736', + "$class->new(11)->blog(undef, 71)"); + +is($class->new(21)->blog(undef, 71), + '3.0445224377234229965005979803657054342845752874046106401940844835750742', + "$class->new(21)->blog(undef, 71)"); + +############################################################################### + +# These tests are now really fast, since they collapse to blog(10), basically +# Don't attempt to run them with older versions. You are warned. + +# $x < 0 => NaN +is($class->new(-2)->blog(), 'NaN', "$class->new(-2)->blog()"); +is($class->new(-1)->blog(), 'NaN', "$class->new(-1)->blog()"); +is($class->new(-10)->blog(), 'NaN', "$class->new(-10)->blog()"); +is($class->new(-2, 2)->blog(), 'NaN', "$class->new(-2, 2)->blog()"); + +my $ten = $class->new(10)->blog(); + +# 10 is cached (up to 75 digits) +is($class->new(10)->blog(), + '2.302585092994045684017991454684364207601', + qq|$class->new(10)->blog()|); + +# 0.1 is using the cached value for log(10), too + +is($class->new("0.1")->blog(), -$ten, + qq|$class->new("0.1")->blog()|); +is($class->new("0.01")->blog(), -$ten * 2, + qq|$class->new("0.01")->blog()|); +is($class->new("0.001")->blog(), -$ten * 3, + qq|$class->new("0.001")->blog()|); +is($class->new("0.0001")->blog(), -$ten * 4, + qq|$class->new("0.0001")->blog()|); + +# also cached +is($class->new(2)->blog(), + '0.6931471805599453094172321214581765680755', + qq|$class->new(2)->blog()|); +is($class->new(4)->blog(), $class->new(2)->blog * 2, + qq|$class->new(4)->blog()|); + +# These are still slow, so do them only to 10 digits + +is($class->new("0.2")->blog(undef, 10), "-1.609437912", + qq|$class->new("0.2")->blog(undef, 10)|); +is($class->new("0.3")->blog(undef, 10), "-1.203972804", + qq|$class->new("0.3")->blog(undef, 10)|); +is($class->new("0.4")->blog(undef, 10), "-0.9162907319", + qq|$class->new("0.4")->blog(undef, 10)|); +is($class->new("0.5")->blog(undef, 10), "-0.6931471806", + qq|$class->new("0.5")->blog(undef, 10)|); +is($class->new("0.6")->blog(undef, 10), "-0.5108256238", + qq|$class->new("0.6")->blog(undef, 10)|); +is($class->new("0.7")->blog(undef, 10), "-0.3566749439", + qq|$class->new("0.7")->blog(undef, 10)|); +is($class->new("0.8")->blog(undef, 10), "-0.2231435513", + qq|$class->new("0.8")->blog(undef, 10)|); +is($class->new("0.9")->blog(undef, 10), "-0.1053605157", + qq|$class->new("0.9")->blog(undef, 10)|); + +is($class->new("9")->blog(undef, 10), "2.197224577", + qq|$class->new("9")->blog(undef, 10)|); + +is($class->new("10")->blog(10, 10), "1.000000000", + qq|$class->new("10")->blog(10, 10)|); +is($class->new("20")->blog(20, 10), "1.000000000", + qq|$class->new("20")->blog(20, 10)|); +is($class->new("100")->blog(100, 10), "1.000000000", + qq|$class->new("100")->blog(100, 10)|); + +is($class->new("100")->blog(10, 10), "2.000000000", # 10 ** 2 == 100 + qq|$class->new("100")->blog(10, 10)|); +is($class->new("400")->blog(20, 10), "2.000000000", # 20 ** 2 == 400 + qq|$class->new("400")->blog(20, 10)|); + +is($class->new("4")->blog(2, 10), "2.000000000", # 2 ** 2 == 4 + qq|$class->new("4")->blog(2, 10)|); +is($class->new("16")->blog(2, 10), "4.000000000", # 2 ** 4 == 16 + qq|$class->new("16")->blog(2, 10)|); + +is($class->new("1.2")->bpow("0.3", 10), "1.056219968", + qq|$class->new("1.2")->bpow("0.3", 10)|); +is($class->new("10")->bpow("0.6", 10), "3.981071706", + qq|$class->new("10")->bpow("0.6", 10)|); + +# blog should handle bigint input +is(Math::BigFloat::blog(Math::BigInt->new(100), 10), 2, "blog(100)"); + +############################################################################### +# some integer results +is($class->new(2)->bpow(32)->blog(2), "32", "2 ** 32"); +is($class->new(3)->bpow(32)->blog(3), "32", "3 ** 32"); +is($class->new(2)->bpow(65)->blog(2), "65", "2 ** 65"); + +my $x = Math::BigInt->new('777') ** 256; +my $base = Math::BigInt->new('12345678901234'); +is($x->copy()->blog($base), 56, 'blog(777**256, 12345678901234)'); + +$x = Math::BigInt->new('777') ** 777; +$base = Math::BigInt->new('777'); +is($x->copy()->blog($base), 777, 'blog(777**777, 777)'); + +############################################################################### +# test for bug in bsqrt() not taking negative _e into account +test_bpow('200', '0.5', 10, '14.14213562'); +test_bpow('20', '0.5', 10, '4.472135955'); +test_bpow('2', '0.5', 10, '1.414213562'); +test_bpow('0.2', '0.5', 10, '0.4472135955'); +test_bpow('0.02', '0.5', 10, '0.1414213562'); +test_bpow('0.49', '0.5', undef, '0.7'); +test_bpow('0.49', '0.5', 10, '0.7000000000'); +test_bpow('0.002', '0.5', 10, '0.04472135955'); +test_bpow('0.0002', '0.5', 10, '0.01414213562'); +test_bpow('0.0049', '0.5', undef, '0.07'); +test_bpow('0.0049', '0.5', 10, '0.07000000000'); +test_bpow('0.000002', '0.5', 10, '0.001414213562'); +test_bpow('0.021', '0.5', 10, '0.1449137675'); +test_bpow('1.2', '0.5', 10, '1.095445115'); +test_bpow('1.23', '0.5', 10, '1.109053651'); +test_bpow('12.3', '0.5', 10, '3.507135583'); + +test_bpow('9.9', '0.5', 10, '3.146426545'); +test_bpow('9.86902225', '0.5', 10, '3.141500000'); +test_bpow('9.86902225', '0.5', undef, '3.1415'); + +############################################################################### +# other tests for bpow() + +test_bpow('0.2', '0.41', 10, '0.5169187652'); + +is($class->new("0.01")->bpow("28.4", 40)->bsstr(), + '1584893192461113485202101373391507013269e-96', + qq|$class->new("0.01")->bpow("28.4", 40)->bsstr()|); + +# The following test takes too long. +#is($class->new("2")->bpow("-1034.5", 40)->bsstr(), +# '3841222690408590466868250378242558090957e-351', +# qq|$class->new("2")->bpow("-1034.5", 40)|); + +############################################################################### +# test bexp() with cached results + +is($class->new(1)->bexp(), '2.718281828459045235360287471352662497757', + 'bexp(1)'); +is($class->new(2)->bexp(40), $class->new(1)->bexp(45)->bpow(2, 40), + 'bexp(2)'); + +is($class->new("12.5")->bexp(61), $class->new(1)->bexp(65)->bpow(12.5, 61), + 'bexp(12.5)'); + +############################################################################### +# test bexp() with big values (non-cached) + +is($class->new(1)->bexp(100), + '2.7182818284590452353602874713526624977572470936999' + . '59574966967627724076630353547594571382178525166427', + qq|$class->new(1)->bexp(100)|); + +is($class->new("12.5")->bexp(91), $class->new(1)->bexp(95)->bpow(12.5, 91), + qq|$class->new("12.5")->bexp(91)|); + +is($class->new("-118.5")->bexp(20)->bsstr(), + '34364014567198602057e-71', + qq|$class->new("-118.5")->bexp(20)->bsstr()|); + +is($class->new("-394.84010945715266885")->bexp(20)->bsstr(), + '33351796227864913873e-191', + qq|$class->new("-118.5")->bexp(20)->bsstr()|); + +# all done + +1; + +############################################################################### + +sub test_bpow { + my ($x, $y, $scale, $result) = @_; + is($class->new($x)->bpow($y, $scale), $result, + qq|$class->new($x)->bpow($y, | + . (defined($scale) ? $scale : 'undef') + . qq|)|); +} diff --git a/cpan/Math-BigInt-FastCalc/t/bigroot.t b/cpan/Math-BigInt-FastCalc/t/bigroot.t new file mode 100644 index 0000000000..c14bca1e2a --- /dev/null +++ b/cpan/Math-BigInt-FastCalc/t/bigroot.t @@ -0,0 +1,53 @@ +#!perl + +# Test broot function (and bsqrt() function, since it is used by broot()). + +# It is too slow to be simple included in bigfltpm.inc, where it would get +# executed 3 times. + +# But it is better to test the numerical functionality, instead of not testing +# it at all. + +use strict; # restrict unsafe constructs +use warnings; # enable optional warnings + +use Test::More tests => 4 * 2; + +use Math::BigFloat only => 'FastCalc'; +use Math::BigInt; + +my $mbf = "Math::BigFloat"; +my $mbi = "Math::BigInt"; + +# 2 ** 240 = +# 1766847064778384329583297500742918515827483896875618958121606201292619776 + +# takes way too long +#test_broot('2', '240', 8, undef, +# '1073741824'); +#test_broot('2', '240', 9, undef, +# '106528681.3099908308759836475139583940127'); +#test_broot('2', '120', 9, undef, +# '10321.27324073880096577298929482324664787'); +#test_broot('2', '120', 17, undef, +# '133.3268493632747279600707813049418888729'); + +test_broot('2', '120', 8, undef, + '32768'); +test_broot('2', '60', 8, undef, + '181.0193359837561662466161566988413540569'); +test_broot('2', '60', 9, undef, + '101.5936673259647663841091609134277286651'); +test_broot('2', '60', 17, undef, + '11.54672461623965153271017217302844672562'); + +sub test_broot { + my ($x, $n, $y, $scale, $expected) = @_; + + my $s = $scale || 'undef'; + is($mbf->new($x)->bpow($n)->broot($y, $scale), $expected, + "Try: $mbf->new($x)->bpow($n)->broot($y, $s) == $expected"); + $expected =~ s/\..*//; + is($mbi->new($x)->bpow($n)->broot($y, $scale), $expected, + "Try: $mbi->new($x)->bpow($n)->broot($y, $s) == $expected"); +} diff --git a/cpan/Math-BigInt-FastCalc/t/bootstrap.t b/cpan/Math-BigInt-FastCalc/t/bootstrap.t index d73afcb47c..6f94bebc88 100644 --- a/cpan/Math-BigInt-FastCalc/t/bootstrap.t +++ b/cpan/Math-BigInt-FastCalc/t/bootstrap.t @@ -5,4 +5,3 @@ use Test::More tests => 1; BEGIN { use_ok('Math::BigInt::FastCalc'); } - diff --git a/cpan/Math-BigInt-FastCalc/t/leak.t b/cpan/Math-BigInt-FastCalc/t/leak.t index 5db38e1dbd..6d0f7464a5 100644 --- a/cpan/Math-BigInt-FastCalc/t/leak.t +++ b/cpan/Math-BigInt-FastCalc/t/leak.t @@ -12,7 +12,9 @@ use Math::BigInt::FastCalc; ############################################################################# package Math::BigInt::FastCalc::LeakCheck; -use parent qw(Math::BigInt::FastCalc); + +use Math::BigInt::FastCalc; +our @ISA = qw< Math::BigInt::FastCalc >; my $destroyed = 0; sub DESTROY { $destroyed++; } @@ -76,4 +78,3 @@ sub _test_acmp my $n_2 = Math::BigInt::FastCalc->_str($n2); is ($destroyed, 1, "_acmp($n_1,$n_2) does not leak memory"); } - diff --git a/cpan/Math-BigInt-FastCalc/t/mbi_rand.t b/cpan/Math-BigInt-FastCalc/t/mbi_rand.t index 4ad473d882..1186e2e144 100644 --- a/cpan/Math-BigInt-FastCalc/t/mbi_rand.t +++ b/cpan/Math-BigInt-FastCalc/t/mbi_rand.t @@ -1,55 +1,100 @@ -#!/usr/bin/perl -w +#!perl use strict; +use warnings; + use Test::More; my $count = 128; -plan(($^O eq 'os390') - ? (skip_all => 'takes too long on os390') : (tests => $count*2)); +plan(($^O eq 'os390') ? (skip_all => 'takes too long on os390') + : (tests => $count*4)); -use Math::BigInt lib => 'FastCalc'; -my $c = 'Math::BigInt'; +use Math::BigInt only => 'FastCalc'; my $length = 128; # If you get a failure here, please re-run the test with the printed seed -# value as input: perl t/mbi_rand.t seed +# value as input "perl t/mbi_rand.t seed" and send me the output + +my $seed = @ARGV == 1 ? $ARGV[0] : int(rand(1165537)); +#diag(" seed: $seed\n"); +srand($seed); + +my $_base_len; +my @_base_len; -my $seed = ($#ARGV == 0) ? $ARGV[0] : int(rand(65537)); -print "# seed: $seed\n"; srand($seed); +#diag(" lib: ", Math::BigInt->config('lib')); +if (Math::BigInt->config('lib') =~ /::Calc/) { + $_base_len = Math::BigInt::Calc->_base_len(); + @_base_len = Math::BigInt::Calc->_base_len(); + #diag("base len: $_base_len (scalar context)"); + #diag("base len: @_base_len (list contex)"); +} -my ($A,$B,$As,$Bs,$ADB,$AMB,$la,$lb); +my ($A, $B, $A_str, $B_str, $AdivB, $AmodB, $A_len, $B_len); my $two = Math::BigInt->new(2); -for (my $i = 0; $i < $count; $i++) - { - # length of A and B - $la = int(rand($length)+1); $lb = int(rand($length)+1); - $As = ''; $Bs = ''; - # we create the numbers from "patterns", e.g. get a random number and a - # random count and string them together. This means things like - # "100000999999999999911122222222" are much more likely. If we just strung - # together digits, we would end up with "1272398823211223" etc. - while (length($As) < $la) { $As .= int(rand(100)) x int(rand(16)); } - while (length($Bs) < $lb) { $Bs .= int(rand(100)) x int(rand(16)); } - $As =~ s/^0+//; $Bs =~ s/^0+//; - $As = $As || '0'; $Bs = $Bs || '0'; - # print "# As $As\n# Bs $Bs\n"; - $A = $c->new($As); $B = $c->new($Bs); - # print "# A $A\n# B $B\n"; - if ($A->is_zero() || $B->is_zero()) - { - is (1,1); is (1,1); next; +for (my $i = 0; $i < $count; $i++) { + #diag(""); + + # length of A and B + $A_len = int(rand($length) + 1); + $B_len = int(rand($length) + 1); + $A_str = ''; + $B_str = ''; + + # We create the numbers from "patterns", e.g. get a random number and a + # random count and string them together. This means things like + # "100000999999999999911122222222" are much more likely. If we just strung + # together digits, we would end up with "1272398823211223" etc. It also + # means that we get more frequently equal numbers or other special cases. + + while (length($A_str) < $A_len) { + $A_str .= int(rand(100)) x int(rand(16)); + } + while (length($B_str) < $B_len) { + $B_str .= int(rand(100)) x int(rand(16)); } - # check that int(A/B)*B + A % B == A holds for all inputs - # $X = ($A/$B)*$B + 2 * ($A % $B) - ($A % $B); - ($ADB,$AMB) = $A->copy()->bdiv($B); - print "# ". join(' ',Math::BigInt::Calc->_base_len()),"\n" - unless is ($ADB*$B+$two*$AMB-$AMB,$As); - # swap 'em and try this, too - # $X = ($B/$A)*$A + $B % $A; - ($ADB,$AMB) = $B->copy()->bdiv($A); - print "# ". join(' ',Math::BigInt::Calc->_base_len()),"\n" - unless is ($ADB*$A+$two*$AMB-$AMB,$Bs); - } + $A_str =~ s/^0+(?=\d)//; + $B_str =~ s/^0+(?=\d)//; + #diag(" As: $A_str"); + #diag(" Bs: $B_str"); + $A = Math::BigInt->new($A_str); + $B = Math::BigInt->new($B_str); + #diag(" A: $A"); + #diag(" B: $B"); + + SKIP: { + skip '$A and/or $B are zero.', 4 if $A->is_zero() || $B->is_zero(); + + # check that int(A / B) * B + A % B == A holds for all inputs + + # $X = ($A / $B) * $B + 2 * ($A % $B) - ($A % $B); + + ($AdivB, $AmodB) = $A->copy()->bdiv($B); + + #diag(" A / B: $AdivB"); + #diag(" A % B: $AmodB"); + + is($AdivB * $B + $two * $AmodB - $AmodB, $A_str, + "AdivB * B + 2 * AmodB - AmodB == A"); + + if (is($AdivB * $B / $B, $AdivB, "AdivB * B / B == AdivB")) { + if (Math::BigInt->config('lib') =~ /::Calc/) { + #diag("AdivB->[-1]: ", $AdivB->{value}->[-1]); + #diag(" B->[-1]: ", $B->{value}->[-1]); + } + } + + # swap 'em and try this, too + # $X = ($B/$A)*$A + $B % $A; + ($AdivB, $AmodB) = $B->copy()->bdiv($A); + # print "check: $AdivB $AmodB"; + + is($AdivB * $A + $two * $AmodB - $AmodB, $B_str, + "AdivB * A + 2 * AmodB - AmodB == B"); + + is($AdivB * $A / $A, $AdivB, "AdivB * A / A == AdivB"); + } +} |