Math-BigInt-GMP-1.37/0000755005434300244210000000000011630745112014065 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/BUGS0000644005434300244210000000033011523750261014546 0ustar OSPJADomain Users Known bugs: * Some problems with left/right shifting in base != 2 seem to occur Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! Tels Math-BigInt-GMP-1.37/build/0000755005434300244210000000000011630745101015162 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/build/leak.pl0000644005434300244210000000240011521227622016431 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; use lib 'lib'; use lib 'blib/arch'; use Math::BigInt lib => 'GMP'; use Devel::Leak; my $x = Math::BigInt->new(44); my $y = Math::BigInt->new(21); require Scalar::Util; # otherwise the first sub would do this my $xg = Math::BigInt::GMP->_new("44"); my $yg = Math::BigInt::GMP->_new("21"); for my $do ( [ sub { $xg = Math::BigInt::GMP->_div($xg,$yg); 1; }, 'divide direct' ], [ sub { my $z = $x / $y; 1; }, 'divide' ], [ sub { my $z = $x - $y; 1; }, 'subtract' ], [ sub { my $z = $x + $y; 1; }, 'add' ], [ sub { my $z = $x % $y; 1; }, 'mod' ], [ sub { my $z = $x ** $y; 1; }, 'pow' ], [ sub { my $z = $x ^ $y; 1; }, 'xor' ], [ sub { my $z = $x | $y; 1; }, 'ior' ], [ sub { my $z = $x & $y; 1; }, 'and' ], [ sub { my $z = $x; $z -= $y; 1; }, '-=' ], [ sub { my $z = $x; $z += $y; 1; }, '+=' ], [ sub { my $z = $x; $z %= $y; 1; }, '%=' ], [ sub { my $z = $x; $z /= $y; 1; }, '/=' ], [ sub { my ($q,$r) = $x->copy()->bdiv($y); 1; }, '(q,r) = x / y' ], [ sub { $x->_trailing_zeros(); }, '_zeros(x)' ], # needs an even number! ) { my $handle; my $count = Devel::Leak::NoteSV($handle); for (1..13) { &{$do->[0]}; } print "$do->[1] leaked ", Devel::Leak::CheckSV($handle) - $count, " things\n"; } exit; Math-BigInt-GMP-1.37/build/leaktest0000755005434300244210000000017311521227622016727 0ustar OSPJADomain Users#!/bin/sh valgrind --leak-check=yes perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t Math-BigInt-GMP-1.37/build/README0000644005434300244210000000016011521227622016041 0ustar OSPJADomain UsersThis directory contains scripts that are used by the developers. They are not necessarily usefull for users :) Math-BigInt-GMP-1.37/CHANGES0000644005434300244210000003546711630744134015102 0ustar OSPJADomain UsersRevision history for Perl extension Math::BigInt::GMP. 2011-09-04 v1.37 pjacklam * Updated test files from the Math::BigInt distribution (Peter John Acklam). * Updated bundled Devel::CheckLib from v0.92 to v0.93 (Peter John Acklam). * Math::BigInt::GMP now requires Math::BigInt v1.997 (Peter John Acklam). * Include "^MYMETA\.(yml|json)\z" in MANIFEST.SKIP. Whereas META.* are generated by the distribution author at packaging time, MYMETA.* are generated by the end user at configure time after any dynamic dependencies are known. (Peter John Acklam) * Changed Makefile.PL so that a "make dist" makes a META.yml and META.json. (Peter John Acklam) * Updated common test files from the Math::BigInt distribution. (Peter John Acklam) 2011-02-26 v1.36 pjacklam (6362 tests) * Change bigintpm.inc to reflect recent changes in the Math::BigInt distribution (Peter John Acklam). * Use a _nok() function more similar to the one in Math::BigInt::Calc (Peter John Acklam). 2011-02-08 v1.35 pjacklam (6361 tests) * Rename files for testing signature, module loading, and POD so the names are within the 8+3 character limit (Peter John Acklam). * Rename method _nok_ok() to the correct _nok(). There ought to have been a test catching an error like that (Peter John Acklam). * Fix _nok() giving wrong output when second input argument is zero (Peter John Acklam). * Fix _nok() so it doesn't modify its second input arg (Peter John Acklam). * Update the included Devel::CheckLib to most recent version as suggested in RE #63055 (Peter John Acklam). * Apply "chmod 0644" to the few test scripts that don't already have that mode (Peter John Acklam). 2011-02-07 v1.34 pjacklam (6361 tests) * Rename _num() to _str(). The old _num() did exactly what _str() is supposed to do, according to the API documentation (Peter John Acklam). * Add a _num() function which (currently) simply numifies the output from _str() (Peter John Acklam). * Clean up whitespace (Peter John Acklam). * Fix POD errors (Peter John Acklam). * Add _nok() method. Now the old claim that Math::BigInt::GMP conforms to API version 2 is actually true (Peter John Acklam). * Edit the test files that were copied from the Math::BigInt distribution, so we now test Math::BigInt against Math::BigInt::GMP, not Math::BigInt::Calc. I had forgotten this when I copied the test files from the Math::BigInt distribution. This reduces the total test count, since some test are not executed with Math::BigInt::GMP (Peter John Acklam). * Replace morse code in 'README' with proper text (Peter John Acklam). * Include '01-load.t' for explicitly testing module loading (Peter John Acklam). * Use more generic code in 'pod.t' and 'pod_cov.t' (Peter John Acklam). 2011-01-30 v1.33 pjacklam (6411 tests) * Fix _modinv() so that it works the same way as _modinv() in other Math::BigInt libraries: The output arguments are an object and the corresponding sign, not undef (Peter John Acklam). * Include most recent versions of the test files from the Math-BigInt distribution (bigfltpm.inc, bigfltpm.t, bigintpm.inc, bigintpm.t, biglog.t, and bigroot.t) (Peter John Acklam). * Include generic SIGNATURE test file (Peter John Acklam). * Required version of Math::BigInt is now 1.99_05 (Peter John Acklam). 2010-09-23 v1.32 rafl 5559 tests * Re-upload 1.31 as a stable release without further changes. 2010-09-21 v1.31 rafl 5559 tests DEVELOPMENT RELEASE * Add hooks for Storable (de-)serialisation. * Avoid failure in the destructor if someone blessed nonsense into our class. 2010-09-20 v1.30 rafl 5558 tests * Re-upload 1.29 as a stable release without further changes. 2010-09-19 v1.29 rafl 5558 tests DEVELOPMENT RELEASE * Attempt to fix a bug in the bundled version Devel::CheckLib. It used to ignore @Config{qw(ccflags ldflags)} and only tried to look for headers and libraries with the compiler's default include- and lib-paths as well as those explicitly asked for by the user. 2010-09-17 v1.28 rafl 5558 tests * Re-upload 1.27 without further changes as a stable release. 2010-09-15 v1.27 rafl 5558 tests DEVELOPMENT RELEASE * Try to support perls older than 5.8.8 again. Tested with 5.8.7 and 5.6.2. 2010-09-14 v1.26 rafl 5558 tests DEVELOPMENT RELEASE * Error out early if libgmp or gmp.h are missing. * Clone Math::BigInt::GMP instances on thread cloning. This should make the module threadsafe. 2010-09-10 v1.25 rafl 5536 tests * Fix tests with Math::BigInt >= 1.90 and depend on it. 2007-07-31 v1.24 Tels 5530 tests * apply patch for warnings about ptr size mismatch under Cygwin (thanx Reini Urban!) * make it work under 5.6.x again by defining SvUOK() (Thanx Marcus Holland-Moritz and Reini Urban!) 2007-07-25 v1.23 Tels 5527 tests * require Math::BigInt 1.87 * fix for _new() (appeared under Cygwin, but possible others, thanx Linda W. (report) and Reini Urban (patch)!) 2007-06-01 v1.22 Tels 5527 tests * require Math::BigInt 1.86 * support api_version() 2 by adding _nok() * fix compilation issues on Mac/Darwin * _log_int() modifies it's argument instead of just returning a different object as result * speed up _log_int() greatly by taking a guess of the result and then improve it, instead of startig with 1 and going up. This means it takes now a more or less constant time, instead of a time proportional to the size/value of the result: Using Math::BigInt::GMP v1.21 baselen 2: 3s (3.22 usr + 0.00 sys = 3.22 CPU) @ 7270/s (n=23411) baselen 2 big: 3s (3.11 usr + 0.06 sys = 3.17 CPU) @ 962/s (n=3051) baselen 3: 3s (3.20 usr + 0.00 sys = 3.20 CPU) @ 1304/s (n=4173) baselen 7: 3s (3.20 usr + 0.00 sys = 3.20 CPU) @ 3306/s (n=10582) baselen 8: 3s (3.14 usr + 0.00 sys = 3.14 CPU) @ 3769/s (n=11836) baselen 11: 3s (3.24 usr + 0.00 sys = 3.24 CPU) @ 4750/s (n=15392) baselen 14: 3s (3.20 usr + 0.00 sys = 3.20 CPU) @ 5835/s (n=18673) baselen 20: 3s (3.10 usr + 0.03 sys = 3.13 CPU) @ 7621/s (n=23855) baselen 3 big: 4s (3.17 usr + 0.00 sys = 3.17 CPU) @ 320/s (n=1016) Using Math::BigInt::GMP v1.22 baselen 2: 3s (3.15 usr + 0.00 sys = 3.15 CPU) @ 16290/s (n=51316) baselen 2 big: 4s (3.21 usr + 0.01 sys = 3.22 CPU) @ 15933/s (n=51306) baselen 3: 4s (3.12 usr + 0.02 sys = 3.14 CPU) @ 15555/s (n=48844) baselen 7: 4s (3.15 usr + 0.07 sys = 3.22 CPU) @ 15658/s (n=50420) baselen 8: 3s (3.18 usr + 0.01 sys = 3.19 CPU) @ 15610/s (n=49797) baselen 11: 3s (3.14 usr + 0.00 sys = 3.14 CPU) @ 15555/s (n=48844) baselen 14: 3s (3.15 usr + 0.00 sys = 3.15 CPU) @ 15506/s (n=48844) baselen 20: 3s (3.14 usr + 0.01 sys = 3.15 CPU) @ 15506/s (n=48844) baselen 3 big: 3s (3.10 usr + 0.04 sys = 3.14 CPU) @ 15555/s (n=48844) 2007-04-17 v1.21 Tels 5488 tests * add _as_oct(), _from_oct(), _alen(), _1ex() and some _root() tests * require Math::BigInt 1.83 * support api_version() by adding _1ex() and _alen() * _new(): take a shortcut if the passed an IV (integer value) 2007-04-09 v1.20 Tels 5351 tests * remove PREREQ_FATAL because the toolchain is broken and cannot handle it * take over tests from MBI 1.82 and require it * require Perl 5.6.2 as minimum * speed up _zeros(): + use Newx() instead of a full-blown SV for temp storage + no need to allocate temp storage for numbers < 10 * put _len() into XS code, making $x->length() faster (about 30% for "123", less for longer numbers as the binary=>decimal conversion dominates) * add POD tests * add MANIFEST.SKIP 2007-01-27 v1.19 Tels 5339 tests * add support for octal * take over tests from MBI 1.78 and require it Older Changelog: 2001-07-22 v1.00 Tels * First version (basically working with some quirks) 2001-08-06 v1.01 Tels * first release * fixed all the bugs in v1.00 * taken over tests from BigInt v1.40 2001-09-02 v1.02 Tels * removed auto-export and added empty import() * taken over tests from BigInt v1.42 2001-11-01 v1.03 Tels * taken over tests from BigInt v1.45 * added _mod() for more speed for $x % $y #!/usr/bin/perl -w use lib 'lib'; #use lib '../Math-BigInt-GMP-1.02/lib'; use Math::BigInt lib => 'GMP'; use Benchmark; my $digits = 1024; my $x = Math::BigInt->new('1' . '0' x $digits); my $y = Math::BigInt->new('3' . '0' x ($digits - 2) . '3'); my $u = Math::BigInt->new('3'); timethese ( 2000, { mod_l => sub { $z = $x % $y, }, mod_s => sub { $z = $x % $u, }, div_l => sub { ($z,$r) = $x->copy()->bdiv($y), }, } ); On a 1 Ghz Athlon with v1.45 of BigInt in ops/s: v1.02 v1.03 mod_s 1100 2350 mod_l 1111 2325 div_l 1260 1300 2001-11-01 v1.04a Tels (never released) * _is_odd()/_is_even() use $two instead of 2: 5600 op/s instead of 4700 2002-01-26 v1.04 Tels * use $zero,$one,$two etc instead of 0,1,2 in some routines * tests from Math::BigInt v1.50 * bypass Math::GMP's overload interface and use Math::GMP::gmp_foo() directly * added _gcd() and _fac() for more speed in bgcd() and bfac(), respectively 2002-02-16 v1.05 Tels * tests from Math::BigInt v1.51 * replaced _core_lib() by config()->{lib} * added _and, _or, _xor (using Math::GMP internal methods) * switched _fac over to use Math::GMP gmp_fac() * added _sqrt() using gmp_sqrt() * used div_two and bdiv_two for _div() * tests for _div() in list context and _mod * added _from_hex() The speedups in band(), bxor(), bior() and bfac() are at least factor 10 for small numbers and quickly raise as the numbers grow ;) The speedup for bmod() and bdiv() aren't that dramatic, but still worth it. 2002-03-23 v1.06 Tels * testsuite from v1.55 - 3874 tests * fixed PREREQUISITES to Math::GMP v2.03, BigInt v1.55 * fixed typos in CHANGES * added _from_bin() 2002-07-07 v1.07 Tels * testsuite from BigInt v1.60 - 4054 tests * fixed PREREQUISITES to BigInt v1.60 2002-12-12 v1.08 Tels 4069 tests (never released) * added implementation of bmodpow() using GMPs mpow_gmp() * release signed by key http://bloodgate.com/tels.asc id 93B84C15 2002-12-15 v1.10a Tels Never released * no longer needs Math::GMP (and Carp), but uses own XS layer * is thus faster (saves one perl subroutine layer) and less memory hungry (it now uses even less memory than using Calc!) new XS lets us cut out a subroutine layer * new XS will enable us to implement *all* missing functions like _root(), _as_hex(), _as_bin() and _rsft(), _lsft() * fixed PREREQ to BigInt v1.65 * extended tests in bigintg.t to cover more functions 2002-12-24 v1.10 Tels 4109 tests * Merry Christmas and a Happy New Year to all! * cut out more dead wood from GMP.xs, GMP.so file shrunk a bit * added some comments in GMP.xs * fixed PREREQ to BigInt v1.64 since v1.65 is not yet out *sigh* * more functions like _is_odd()/_is_even()/_acmp() directly in XS - cut away perl layer subroutines for more speed (about 10-30% more ops/s for small argument or constant cases or other cases where the overhead is greater than the actual math operation itself) * __stringify() no longer malloc()s a temp. storage => faster * added _root(), _lsft() and_rsft() functions for great speedups * Running the benchmark script above (adopted a bit) on the same 1 Ghz AMD under BigInt v1.64: Benchmark: running div_l, mod_l, mod_s for at least 3 CPU seconds... div_l: 3s ( 3.20 usr + 0.00 sys = 3.20 CPU) @ 4655.00/s (n=14896) mod_l: 4s ( 3.31 usr + 0.00 sys = 3.31 CPU) @ 6851.96/s (n=22680) mod_s: 3s ( 3.01 usr + 0.00 sys = 3.01 CPU) @ 7088.37/s (n=21336) * Full (memory and other) benchmarks at http://bloodgate.com/perl/bigint/ 2003-01-01 v1.11 Tels 4109 tests * rewrote stringify_bin() and stringify_hex() to not allocate scratch buffers Faster, no longer needs malloc()/free() and strlen(). Thanx to Sysiphus for pointing this out. * removed _as_hex() and _as_bin() from GMP.pm and moved the logic to GMP.xs * documented in todo to replace all malloc()/free() with New and Safefree() * removed unused cmp_two() function in GMP.xs * removed the unused "$zero = ..."/"$one = ..." in GMP.pm 2003-01-08 v1.12a Tels 4109 tests (not released) * removed unused function _mmod from XS code * removed unnecc. if len == 0 check in _as_bin(), _as_hex() etc * replace some RETVAL = malloc() lines with defined to make changing them later much easier 2003-07-04 v1.12b Tels 4491 tests (not released) * testsuite from v1.65 * fixed prereq to require BigInt v1.65 2003-12-11 v1.12 Tels 4677 tests * testsuite from v1.67, especialy revamped bigintg.t * fixed prereq to require BigInt v1.67 * added _log_int() to XS code * some routines did only return the result, but not modify $x in place 2004-01-10 v1.13 Tels 4759 tests * tests from BigInt v1.68 * removed DESTROY from GMP.pm and made GMP.xs destroy => DESTROY * removed _num from GMP.pm and made GMP.xs __stringify => _num * removed _modinv() from GMP.pm and fixed up _modinv in GMP.xs * disabled the borken _log_int() from the XS code * modify $x in place for _dec, _inc, _add, _mod, _mul, _fac, _and, _or, _xor, _sqrt, _root and _sub (sub in non-reversed form), this removes some malloc/free and makes these ops slightly faster (between 10 and 33% in Math::BigInt (!), depending on input and size) 2004-02-15 v1.14 Tels 4867 tests * require BigInt v1.70, use tests from it and make API compatible with it * _rsft() and _lsft() modify their argument instead of making a copy, meaning brsft() and blsft() got about 20% faster in BigInt * added a working _zeros() method * added a working _log_int() method 2004-11-22 v1.15 Tels 5112 tests * some small cleanups in the Perl code * changed "class" to "Class" to avoid the reserved keyword for MS compiler * do not pull unused parameter "Class" from stack - avoid compiler warnings * put _sub() into XS for more speed and smaller memory footprint * testsuite from MBI v1.73 2004-12-09 v1.16 Tels 5112 tests * fixed a leak in _div() (Thanx Tassilo v. Parsival!) * put _div() into XS, making division slightly faster for small numbers * put leak.pl and leaktest into MANIFEST for later checking 2005-01-01 v1.17 Tels 5182 tests * use XSLoader instead of DynaLoader to save a tiny amount of memory * take over tests from Math::BigInt v1.74 * require Math::BigInt v1.74 * simplify sub code in XS (left-over artifact from v1.16) * fix a leak in _zeros() * _zeros() is now much faster for odd numbers (O(1) vs. O(N*N)) 2005-04-11 v1.18 Tels 5186 tests * _log_int() handles now plain scalars as $base parameter * take over tests from MBI 1.76, require it Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! Tels Math-BigInt-GMP-1.37/CREDITS0000644005434300244210000000027211523750122015104 0ustar OSPJADomain Users * Sysiphus for commenting on my work, pointing out the strlen() and malloc issues * Chip Turner for the XS code from Math::GMP * All the people working on the GMP library - you rock! Math-BigInt-GMP-1.37/GMP.xs0000644005434300244210000005341511523750266015103 0ustar OSPJADomain Users#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "gmp.h" typedef mpz_t mpz_t_ornull; /* for Perl prior to v5.7.1 */ #ifndef SvUOK # define SvUOK(sv) SvIOK_UV(sv) #endif #ifndef PERL_UNUSED_ARG # define PERL_UNUSED_ARG(x) ((void)x) #endif #ifndef gv_stashpvs # define gv_stashpvs(name, create) gv_stashpvn(name, sizeof(name) - 1, create) #endif #ifndef PERL_MAGIC_ext # define PERL_MAGIC_ext '~' #endif #if defined(USE_ITHREADS) && defined(MGf_DUP) # define GMP_THREADSAFE 1 #else # define GMP_THREADSAFE 0 #endif #ifdef sv_magicext # define GMP_HAS_MAGICEXT 1 #else # define GMP_HAS_MAGICEXT 0 #endif #define NEW_GMP_MPZ_T RETVAL = malloc (sizeof(mpz_t)); #define NEW_GMP_MPZ_T_INIT RETVAL = malloc (sizeof(mpz_t)); mpz_init(*RETVAL); #define GMP_GET_ARG_0 TEMP = mpz_from_sv(x); #define GMP_GET_ARG_1 TEMP_1 = mpz_from_sv(y); #define GMP_GET_ARGS_0_1 GMP_GET_ARG_0; GMP_GET_ARG_1; #if GMP_THREADSAFE STATIC int dup_gmp_mpz (pTHX_ MAGIC *mg, CLONE_PARAMS *params) { mpz_t *RETVAL; PERL_UNUSED_ARG(params); NEW_GMP_MPZ_T; mpz_init_set(*RETVAL, *((mpz_t *)mg->mg_ptr)); mg->mg_ptr = (char *)RETVAL; return 0; } #endif #if GMP_HAS_MAGICEXT STATIC MGVTBL vtbl_gmp = { NULL, /* get */ NULL, /* set */ NULL, /* len */ NULL, /* clear */ NULL, /* free */ # ifdef MGf_COPY NULL, /* copy */ # endif # ifdef MGf_DUP # if GMP_THREADSAFE dup_gmp_mpz, # else NULL, /* dup */ # endif # endif # ifdef MGf_LOCAL NULL, /* local */ # endif }; #endif STATIC void attach_mpz_to_sv (SV *sv, mpz_t *mpz) { #if GMP_THREADSAFE MAGIC *mg; #endif #if !GMP_HAS_MAGICEXT SV *refaddr = sv_2mortal(newSViv(PTR2IV(mpz))); #endif sv_bless(sv, gv_stashpvs("Math::BigInt::GMP", 0)); #if GMP_THREADSAFE && GMP_HAS_MAGICEXT mg = #endif #if GMP_HAS_MAGICEXT sv_magicext(SvRV(sv), NULL, PERL_MAGIC_ext, &vtbl_gmp, (void *)mpz, 0); #else sv_magic(SvRV(sv), NULL, PERL_MAGIC_ext, (void *)refaddr, HEf_SVKEY); #endif #if GMP_THREADSAFE && GMP_HAS_MAGICEXT mg->mg_flags |= MGf_DUP; #endif } STATIC SV * sv_from_mpz (mpz_t *mpz) { SV *sv = newSV(0); SV *obj = newRV_noinc(sv); attach_mpz_to_sv(obj, mpz); return obj; } STATIC mpz_t * mpz_from_sv_nofail (SV *sv) { MAGIC *mg; if (!sv_derived_from(sv, "Math::BigInt::GMP")) croak("not of type Math::BigInt::GMP"); for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) { if (mg->mg_type == PERL_MAGIC_ext #if GMP_HAS_MAGICEXT && mg->mg_virtual == &vtbl_gmp #endif ) { #if GMP_HAS_MAGICEXT return (mpz_t *)mg->mg_ptr; #else return INT2PTR(mpz_t *, SvIV((SV *)mg->mg_ptr)); #endif } } return (mpz_t *)NULL; } STATIC mpz_t * mpz_from_sv (SV *sv) { mpz_t *mpz; if (!(mpz = mpz_from_sv_nofail(sv))) croak("failed to fetch mpz pointer"); return mpz; } /* Math::BigInt::GMP XS code, loosely based on Math::GMP, a Perl module for high-speed arbitrary size integer calculations (C) 2000 James H. Turner */ MODULE = Math::BigInt::GMP PACKAGE = Math::BigInt::GMP PROTOTYPES: ENABLE ############################################################################## # _new() mpz_t * _new(Class,x) SV* x CODE: NEW_GMP_MPZ_T; /* using the IV directly is a bit faster */ if (SvUOK(x)) { mpz_init_set_si(*RETVAL, (UV)SvUV(x)); } else { mpz_init_set_str(*RETVAL, SvPV_nolen(x), 10); } OUTPUT: RETVAL ############################################################################## # _new_attach() void _new_attach(Class,sv,x) SV *sv SV *x PREINIT: mpz_t *mpz; CODE: mpz = malloc (sizeof(mpz_t)); if (SvUOK(x)) { mpz_init_set_si(*mpz, (UV)SvUV(x)); } else { mpz_init_set_str(*mpz, SvPV_nolen(x), 10); } attach_mpz_to_sv(sv, mpz); ############################################################################## # _from_bin() mpz_t * _from_bin(Class,x) SV* x CODE: NEW_GMP_MPZ_T; mpz_init_set_str(*RETVAL, SvPV_nolen(x), 0); OUTPUT: RETVAL ############################################################################## # _from_hex() mpz_t * _from_hex(Class,x) SV* x CODE: NEW_GMP_MPZ_T; mpz_init_set_str(*RETVAL, SvPV_nolen(x), 0); OUTPUT: RETVAL ############################################################################## # _from_oct() mpz_t * _from_oct(Class,x) SV* x CODE: NEW_GMP_MPZ_T; mpz_init_set_str(*RETVAL, SvPV_nolen(x), 0); OUTPUT: RETVAL ############################################################################## # _set() - set an already existing object to the given scalar value void _set(Class,n,x) mpz_t* n SV* x CODE: mpz_init_set_ui(*n, SvIV(x)); ############################################################################## # _zero() mpz_t * _zero(Class) CODE: NEW_GMP_MPZ_T; mpz_init_set_ui(*RETVAL, 0); OUTPUT: RETVAL ############################################################################## # _one() mpz_t * _one(Class) CODE: NEW_GMP_MPZ_T; mpz_init_set_ui(*RETVAL, 1); OUTPUT: RETVAL ############################################################################## # _two() mpz_t * _two(Class) CODE: NEW_GMP_MPZ_T; mpz_init_set_ui(*RETVAL, 2); OUTPUT: RETVAL ############################################################################## # _ten() mpz_t * _ten(Class) CODE: NEW_GMP_MPZ_T; mpz_init_set_ui(*RETVAL, 10); OUTPUT: RETVAL ############################################################################## # _1ex() mpz_t * _1ex(Class,x) int x; CODE: NEW_GMP_MPZ_T; mpz_init_set_ui(*RETVAL, 10); mpz_pow_ui(*RETVAL, *RETVAL, x); OUTPUT: RETVAL ############################################################################## # DESTROY() - free memory of a GMP number void DESTROY(n) mpz_t_ornull* n PPCODE: if (n) { mpz_clear(*n); free(n); } ############################################################################## # _str() - return string so that atof() and atoi() can use it SV * _str(Class, n) mpz_t* n PREINIT: int len; char *buf; char *buf_end; CODE: /* len is always >= 1, and might be off (greater) by one than real len */ len = mpz_sizeinbase(*n, 10); RETVAL = newSV(len); /* alloc len +1 bytes */ SvPOK_on(RETVAL); buf = SvPVX(RETVAL); /* get ptr to storage */ buf_end = buf + len - 1; /* end of storage (-1)*/ mpz_get_str(buf, 10, *n); /* convert to decimal string */ if (*buf_end == 0) { len --; /* got one shorter than expected */ } SvCUR_set(RETVAL, len); /* so set real length */ OUTPUT: RETVAL ############################################################################## # _len() - return the length of the number in base 10 (costly) int _len(Class, n) mpz_t* n PREINIT: char *buf; char *buf_end; CODE: /* len is always >= 1, and might be off (greater) by one than real len */ RETVAL = mpz_sizeinbase(*n, 10); if (RETVAL > 1) /* is at least 10? */ { New(0, buf, RETVAL + 1, I8); /* alloc scratch buffer (len+1) bytes */ buf_end = buf + RETVAL - 1; /* end of storage (-1)*/ mpz_get_str(buf, 10, *n); /* convert to decimal string */ if (*buf_end == 0) { RETVAL --; /* got one shorter than expected */ } Safefree(buf); /* free the scratch buffer */ } OUTPUT: RETVAL ############################################################################## # _alen() - return the approx. length of the number in base 10 (fast) int _alen(Class, n) mpz_t* n CODE: /* len is always >= 1, and might be off (greater) by one than real len */ RETVAL = mpz_sizeinbase(*n, 10); OUTPUT: RETVAL ############################################################################## # _zeros() - return number of trailing zeros (in decimal form) # This is costly, since it needs O(N*N) to convert the number to decimal, # even though for most cases the number does not have many trailing zeros. # For numbers longer than X digits (10?) we could divide repeatable by 1e5 # or something and see if we get zeros. int _zeros(Class,n) mpz_t* n PREINIT: int len; char *buf; char *buf_end; CODE: /* odd numbers can not have trailing zeros */ RETVAL = 1 - mpz_tstbit(*n,0); if (RETVAL != 0) /* was even */ { /* len is always >= 1, and might be off (greater) by one than real len */ RETVAL = 0; len = mpz_sizeinbase(*n, 10); if (len > 1) /* '0' has no trailing zeros! */ { New(0, buf, len + 1, I8); mpz_get_str(buf, 10, *n); /* convert to decimal string */ buf_end = buf + len - 1; if (*buf_end == 0) /* points to terminating zero? */ { buf_end--; /* ptr to last real digit */ len--; /* got one shorter than expected */ } while (len-- > 0) /* actually, we should hit a non-zero before the end */ { if (*buf_end-- != '0') { break; } RETVAL++; } Safefree(buf); /* free the scratch buffer */ } } /* end if n was even */ OUTPUT: RETVAL ############################################################################## # _as_hex() - return ref to hexadecimal string (prefixed with 0x) SV * _as_hex(Class,n) mpz_t * n PREINIT: int len; char *buf; CODE: /* len is always >= 1, and accurate (unlike in decimal) */ len = mpz_sizeinbase(*n, 16) + 2; RETVAL = newSV(len); /* alloc len +1 (+2 for '0x') bytes */ SvPOK_on(RETVAL); buf = SvPVX(RETVAL); /* get ptr to storage */ *buf++ = '0'; *buf++ = 'x'; /* prepend '0x' */ mpz_get_str(buf, 16, *n); /* convert to hexadecimal string */ SvCUR_set(RETVAL, len); /* so set real length */ OUTPUT: RETVAL ############################################################################## # _as_bin() - return ref to binary string (prefixed with 0b) SV * _as_bin(Class,n) mpz_t * n PREINIT: int len; char *buf; CODE: /* len is always >= 1, and accurate (unlike in decimal) */ len = mpz_sizeinbase(*n, 2) + 2; RETVAL = newSV(len); /* alloc len +1 (+2 for '0b') bytes */ SvPOK_on(RETVAL); buf = SvPVX(RETVAL); /* get ptr to storage */ *buf++ = '0'; *buf++ = 'b'; /* prepend '0b' */ mpz_get_str(buf, 2, *n); /* convert to binary string */ SvCUR_set(RETVAL, len); /* so set real length */ OUTPUT: RETVAL ############################################################################## # _as_oct() - return ref to octal string (prefixed with 0) SV * _as_oct(Class,n) mpz_t * n PREINIT: int len; char *buf; CODE: /* len is always >= 1, and accurate (unlike in decimal) */ len = mpz_sizeinbase(*n, 8) + 1; RETVAL = newSV(len); /* alloc len +1 (+1 for '0') bytes */ SvPOK_on(RETVAL); buf = SvPVX(RETVAL); /* get ptr to storage */ *buf++ = '0'; /* prepend '0' */ mpz_get_str(buf, 8, *n); /* convert to binary string */ SvCUR_set(RETVAL, len); /* so set real length */ OUTPUT: RETVAL ############################################################################## # _modpow() - ($n ** $exp) % $mod mpz_t * _modpow(Class, n, exp, mod) mpz_t* n mpz_t* exp mpz_t* mod CODE: NEW_GMP_MPZ_T_INIT; mpz_powm(*RETVAL, *n, *exp, *mod); OUTPUT: RETVAL ############################################################################## # _modinv() - compute the inverse of x % y # # int mpz_invert (mpz_t rop, mpz_t op1, mpz_t op2) Function # Compute the inverse of op1 modulo op2 and put the result in rop. If the # inverse exists, the return value is non-zero and rop will satisfy # 0 <= rop < op2. If an inverse doesn't exist the return value is zero and rop # is undefined. void _modinv(Class,x,y) mpz_t* x mpz_t* y PREINIT: int rc, sign; SV* s; mpz_t* RETVAL; PPCODE: NEW_GMP_MPZ_T_INIT; rc = mpz_invert(*RETVAL, *x, *y); EXTEND(SP, 2); /* we return two values */ if (rc == 0) { /* Inverse doesn't exist. Return both values undefined. */ PUSHs ( &PL_sv_undef ); PUSHs ( &PL_sv_undef ); } else { /* Inverse exists. When the modulus to mpz_invert() is positive, * the returned value is also positive. */ PUSHs(sv_2mortal(sv_from_mpz(RETVAL))); s = sv_newmortal(); sv_setpvn (s, "+", 1); PUSHs ( s ); } ############################################################################## # _add() - add $y to $x in place void _add(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_add(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _inc() - modify x inline by doing x++ void _inc(Class,x) SV* x PREINIT: mpz_t* TEMP; PPCODE: GMP_GET_ARG_0; /* TEMP = mpz_t(x) */ mpz_add_ui(*TEMP, *TEMP, 1); PUSHs( x ); ############################################################################## # _dec() - modify x inline by doing x-- void _dec(Class,x) SV* x PREINIT: mpz_t* TEMP; PPCODE: GMP_GET_ARG_0; /* TEMP = mpz_t(x) */ mpz_sub_ui(*TEMP, *TEMP, 1); PUSHs( x ); ############################################################################## # _sub() - $x - $y # $x is always larger than $y! So overflow/underflow can not happen here. # Formerly this code was: # # if ($_[3]) # { # $_[2] = Math::BigInt::GMP::sub_two($_[1],$_[2]); return $_[2]; # } # Math::BigInt::GMP::_sub_in_place($_[1],$_[2]); # } void _sub(Class,x,y, ...) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ if ( items == 4 && SvTRUE(ST(3)) ) { /* y -= x */ mpz_sub(*TEMP_1, *TEMP, *TEMP_1); PUSHs( y ); } else { /* x -= y */ mpz_sub(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); } ############################################################################## # _rsft() void _rsft(Class,x,y,base_sv) SV* x SV* y SV* base_sv PREINIT: unsigned long y_ui; mpz_t* TEMP; mpz_t* TEMP_1; mpz_t* BASE; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ y_ui = mpz_get_ui(*TEMP_1); BASE = malloc (sizeof(mpz_t)); mpz_init_set_ui(*BASE,SvUV(base_sv)); mpz_pow_ui(*BASE, *BASE, y_ui); /* ">> 3 in base 4" => "x / (4 ** 3)" */ mpz_div(*TEMP, *TEMP, *BASE); mpz_clear(*BASE); free(BASE); PUSHs( x ); ############################################################################## # _lsft() void _lsft(Class,x,y,base_sv) SV* x SV* y SV* base_sv PREINIT: unsigned long y_ui; mpz_t* TEMP; mpz_t* TEMP_1; mpz_t* BASE; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ y_ui = mpz_get_ui(*TEMP_1); BASE = malloc (sizeof(mpz_t)); mpz_init_set_ui(*BASE,SvUV(base_sv)); mpz_pow_ui(*BASE, *BASE, y_ui); /* "<< 3 in base 4" => "x * (4 ** 3)" */ mpz_mul(*TEMP, *TEMP, *BASE); mpz_clear(*BASE); free(BASE); PUSHs ( x ); ############################################################################## # _mul() void _mul(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_mul(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _div(): x /= y or (x,rem) = x / y # was in perl: #sub _div # { # i f (wantarray) # { # # return (a/b,a%b) # my $r; # ($_[1],$r) = Math::BigInt::GMP::bdiv_two($_[1],$_[2]); # return ($_[1], $r); # } # # return a / b # Math::BigInt::GMP::div_two($_[1],$_[2]); # } void _div(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; mpz_t * rem; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ if (GIMME_V == G_ARRAY) { /* former bdiv_two() routine */ rem = malloc (sizeof(mpz_t)); mpz_init(*rem); mpz_tdiv_qr(*TEMP, *rem, *TEMP, *TEMP_1); EXTEND(SP, 2); PUSHs( x ); PUSHs(sv_2mortal(sv_from_mpz(rem))); } else { /* former div_two() routine */ mpz_div(*TEMP, *TEMP, *TEMP_1); /* x /= y */ PUSHs( x ); } ############################################################################## # _mod() - x %= y void _mod(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_mod(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _acmp() - cmp two numbers int _acmp(Class,m,n) mpz_t * m mpz_t * n CODE: RETVAL = mpz_cmp(*m, *n); if ( RETVAL < 0) { RETVAL = -1; } if ( RETVAL > 0) { RETVAL = 1; } OUTPUT: RETVAL ############################################################################## # _is_zero() int _is_zero(Class,x) mpz_t * x CODE: RETVAL = mpz_cmp_ui(*x, 0); if ( RETVAL != 0) { RETVAL = 0; } else { RETVAL = 1; } OUTPUT: RETVAL ############################################################################## # _is_one() int _is_one(Class,x) mpz_t * x CODE: RETVAL = mpz_cmp_ui(*x, 1); if ( RETVAL != 0) { RETVAL = 0; } else { RETVAL = 1; } OUTPUT: RETVAL ############################################################################## # _is_two() int _is_two(Class,x) mpz_t * x CODE: RETVAL = mpz_cmp_ui(*x, 2); if ( RETVAL != 0) { RETVAL = 0; } else { RETVAL = 1; } OUTPUT: RETVAL ############################################################################## # _is_ten() int _is_ten(Class,x) mpz_t * x CODE: RETVAL = mpz_cmp_ui(*x, 10); if ( RETVAL != 0) { RETVAL = 0; } else { RETVAL = 1; } OUTPUT: RETVAL ############################################################################## # _pow() - x **= y void _pow(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_pow_ui(*TEMP, *TEMP, mpz_get_ui( *TEMP_1 ) ); PUSHs( x ); ############################################################################## # _gcd() - gcd(m,n) mpz_t * _gcd(Class,x,y) mpz_t* x mpz_t* y CODE: NEW_GMP_MPZ_T_INIT; mpz_gcd(*RETVAL, *x, *y); OUTPUT: RETVAL ############################################################################## # _and() - m &= n void _and(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_and(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _xor() - m =^ n void _xor(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_xor(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _or() - m =| n void _or(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_ior(*TEMP, *TEMP, *TEMP_1); PUSHs( x ); ############################################################################## # _fac() - n! (factorial) void _fac(Class,x) SV* x PREINIT: mpz_t* TEMP; PPCODE: GMP_GET_ARG_0; /* TEMP = x */ mpz_fac_ui(*TEMP, mpz_get_ui(*TEMP)); PUSHs( x ); ############################################################################## # _copy() mpz_t * _copy(Class,m) mpz_t* m CODE: NEW_GMP_MPZ_T; mpz_init_set(*RETVAL, *m); OUTPUT: RETVAL ############################################################################## # _is_odd() - test for number being odd int _is_odd(Class,n) mpz_t* n CODE: RETVAL = mpz_tstbit(*n,0); OUTPUT: RETVAL ############################################################################## # _is_even() - test for number being even int _is_even(Class,n) mpz_t* n CODE: RETVAL = ! mpz_tstbit(*n,0); OUTPUT: RETVAL ############################################################################## # _sqrt() - square root void _sqrt(Class,x) SV* x PREINIT: mpz_t* TEMP; PPCODE: GMP_GET_ARG_0; /* TEMP = x */ mpz_sqrt(*TEMP, *TEMP); PUSHs( x ); ############################################################################## # _root() - integer roots void _root(Class,x,y) SV* x SV* y PREINIT: mpz_t* TEMP; mpz_t* TEMP_1; PPCODE: GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */ mpz_root(*TEMP, *TEMP, mpz_get_ui(*TEMP_1)); PUSHs( x ); Math-BigInt-GMP-1.37/inc/0000755005434300244210000000000011630745101014634 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/inc/Devel/0000755005434300244210000000000011630745101015673 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/inc/Devel/CheckLib.pm0000444005434300244210000003324611547630462017715 0ustar OSPJADomain Users# $Id: CheckLib.pm,v 1.25 2008/10/27 12:16:23 drhyde Exp $ package Devel::CheckLib; use 5.00405; #postfix foreach use strict; use vars qw($VERSION @ISA @EXPORT); $VERSION = '0.93'; use Config qw(%Config); use Text::ParseWords 'quotewords'; use File::Spec; use File::Temp; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(assert_lib check_lib_or_exit check_lib); # localising prevents the warningness leaking out of this module local $^W = 1; # use warnings is a 5.6-ism _findcc(); # bomb out early if there's no compiler =head1 NAME Devel::CheckLib - check that a library is available =head1 DESCRIPTION Devel::CheckLib is a perl module that checks whether a particular C library and its headers are available. =head1 SYNOPSIS use Devel::CheckLib; check_lib_or_exit( lib => 'jpeg', header => 'jpeglib.h' ); check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] ); # or prompt for path to library and then do this: check_lib_or_exit( lib => 'jpeg', libpath => $additional_path ); =head1 USING IT IN Makefile.PL or Build.PL If you want to use this from Makefile.PL or Build.PL, do not simply copy the module into your distribution as this may cause problems when PAUSE and search.cpan.org index the distro. Instead, use the use-devel-checklib script. =head1 HOW IT WORKS You pass named parameters to a function, describing to it how to build and link to the libraries. It works by trying to compile some code - which defaults to this: int main(void) { return 0; } and linking it to the specified libraries. If something pops out the end which looks executable, it gets executed, and if main() returns 0 we know that it worked. That tiny program is built once for each library that you specify, and (without linking) once for each header file. If you want to check for the presence of particular functions in a library, or even that those functions return particular results, then you can pass your own function body for main() thus: check_lib_or_exit( function => 'foo();if(libversion() > 5) return 0; else return 1;' incpath => ... libpath => ... lib => ... header => ... ); In that case, it will fail to build if either foo() or libversion() don't exist, and main() will return the wrong value if libversion()'s return value isn't what you want. =head1 FUNCTIONS All of these take the same named parameters and are exported by default. To avoid exporting them, C. =head2 assert_lib This takes several named parameters, all of which are optional, and dies with an error message if any of the libraries listed can not be found. B: dying in a Makefile.PL or Build.PL may provoke a 'FAIL' report from CPAN Testers' automated smoke testers. Use C instead. The named parameters are: =over =item lib Must be either a string with the name of a single library or a reference to an array of strings of library names. Depending on the compiler found, library names will be fed to the compiler either as C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C) =item libpath a string or an array of strings representing additional paths to search for libraries. =item LIBS a C-style space-seperated list of libraries (each preceded by '-l') and directories (preceded by '-L'). This can also be supplied on the command-line. =back And libraries are no use without header files, so ... =over =item header Must be either a string with the name of a single header file or a reference to an array of strings of header file names. =item incpath a string or an array of strings representing additional paths to search for headers. =item INC a C-style space-seperated list of incpaths, each preceded by '-I'. This can also be supplied on the command-line. =back =head2 check_lib_or_exit This behaves exactly the same as C except that instead of dieing, it warns (with exactly the same error message) and exits. This is intended for use in Makefile.PL / Build.PL when you might want to prompt the user for various paths and things before checking that what they've told you is sane. If any library or header is missing, it exits with an exit value of 0 to avoid causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this result -- which is what you want if an external library dependency is not available. =head2 check_lib This behaves exactly the same as C except that it is silent, returning false instead of dieing, or true otherwise. =cut sub check_lib_or_exit { eval 'assert_lib(@_)'; if($@) { warn $@; exit; } } sub check_lib { eval 'assert_lib(@_)'; return $@ ? 0 : 1; } sub assert_lib { my %args = @_; my (@libs, @libpaths, @headers, @incpaths); # FIXME: these four just SCREAM "refactor" at me @libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib}) if $args{lib}; @libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath}) if $args{libpath}; @headers = (ref($args{header}) ? @{$args{header}} : $args{header}) if $args{header}; @incpaths = (ref($args{incpath}) ? @{$args{incpath}} : $args{incpath}) if $args{incpath}; # work-a-like for Makefile.PL's LIBS and INC arguments # if given as command-line argument, append to %args for my $arg (@ARGV) { for my $mm_attr_key (qw(LIBS INC)) { if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) { # it is tempting to put some \s* into the expression, but the # MM command-line parser only accepts LIBS etc. followed by =, # so we should not be any more lenient with whitespace than that $args{$mm_attr_key} .= " $mm_attr_value"; } } } # using special form of split to trim whitespace if(defined($args{LIBS})) { foreach my $arg (split(' ', $args{LIBS})) { die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-l/i); push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2); } } if(defined($args{INC})) { foreach my $arg (split(' ', $args{INC})) { die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/); push @incpaths, substr($arg, 2); } } my @cc = _findcc(); my @missing; my @wrongresult; my @use_headers; # first figure out which headers we can't find ... for my $header (@headers) { push @use_headers, $header; my($ch, $cfile) = File::Temp::tempfile( 'assertlibXXXXXXXX', SUFFIX => '.c' ); print $ch qq{#include <$_>\n} for @use_headers; print $ch qq{int main(void) { return 0; }\n}; close($ch); my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe}; my @sys_cmd; # FIXME: re-factor - almost identical code later when linking if ( $Config{cc} eq 'cl' ) { # Microsoft compiler require Win32; @sys_cmd = ( @cc, $cfile, "/Fe$exefile", (map { '/I'.Win32::GetShortPathName($_) } @incpaths) ); } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland @sys_cmd = ( @cc, (map { "-I$_" } @incpaths), "-o$exefile", $cfile ); } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ... @sys_cmd = ( @cc, $cfile, (map { "-I$_" } @incpaths), "-o", "$exefile" ); } warn "# @sys_cmd\n" if $args{debug}; my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd); push @missing, $header if $rv != 0 || ! -x $exefile; _cleanup_exe($exefile); unlink $cfile; } # now do each library in turn with headers my($ch, $cfile) = File::Temp::tempfile( 'assertlibXXXXXXXX', SUFFIX => '.c' ); print $ch qq{#include <$_>\n} foreach (@headers); print $ch "int main(void) { ".($args{function} || 'return 0;')." }\n"; close($ch); for my $lib ( @libs ) { my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe}; my @sys_cmd; if ( $Config{cc} eq 'cl' ) { # Microsoft compiler require Win32; my @libpath = map { q{/libpath:} . Win32::GetShortPathName($_) } @libpaths; # this is horribly sensitive to the order of arguments @sys_cmd = ( @cc, $cfile, "${lib}.lib", "/Fe$exefile", (map { '/I'.Win32::GetShortPathName($_) } @incpaths), "/link", (map {'/libpath:'.Win32::GetShortPathName($_)} @libpaths), ); } elsif($Config{cc} eq 'CC/DECC') { # VMS } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland @sys_cmd = ( @cc, "-o$exefile", "-l$lib", (map { "-I$_" } @incpaths), (map { "-L$_" } @libpaths), $cfile); } else { # Unix-ish # gcc, Sun, AIX (gcc, cc) @sys_cmd = ( @cc, $cfile, "-o", "$exefile", "-l$lib", (map { "-I$_" } @incpaths), (map { "-L$_" } @libpaths) ); } warn "# @sys_cmd\n" if $args{debug}; my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd); push @missing, $lib if $rv != 0 || ! -x $exefile; my $absexefile = File::Spec->rel2abs($exefile); $absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/; push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0; _cleanup_exe($exefile); } unlink $cfile; my $miss_string = join( q{, }, map { qq{'$_'} } @missing ); die("Can't link/include $miss_string\n") if @missing; my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult); die("wrong result: $wrong_string\n") if @wrongresult; } sub _cleanup_exe { my ($exefile) = @_; my $ofile = $exefile; $ofile =~ s/$Config{_exe}$/$Config{_o}/; unlink $exefile if -f $exefile; unlink $ofile if -f $ofile; unlink "$exefile\.manifest" if -f "$exefile\.manifest"; return } sub _findcc { # Need to use $keep=1 to work with MSWin32 backslashes and quotes my @Config_ccflags_ldflags = @Config{qw(ccflags ldflags)}; # use copy so ASPerl will compile my @flags = grep { length } map { quotewords('\s+', 1, $_ || ()) } @Config_ccflags_ldflags; my @paths = split(/$Config{path_sep}/, $ENV{PATH}); my @cc = split(/\s+/, $Config{cc}); return (@cc, @flags) if -x $cc[0]; foreach my $path (@paths) { my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe}; return ($compiler, @cc[1 .. $#cc], @flags) if -x $compiler; } die("Couldn't find your C compiler\n"); } # code substantially borrowed from IPC::Run3 sub _quiet_system { my (@cmd) = @_; # save handles local *STDOUT_SAVE; local *STDERR_SAVE; open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT"; open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR"; # redirect to nowhere local *DEV_NULL; open DEV_NULL, ">" . File::Spec->devnull or die "CheckLib: $! opening handle to null device"; open STDOUT, ">&" . fileno DEV_NULL or die "CheckLib: $! redirecting STDOUT to null handle"; open STDERR, ">&" . fileno DEV_NULL or die "CheckLib: $! redirecting STDERR to null handle"; # run system command my $rv = system(@cmd); # restore handles open STDOUT, ">&" . fileno STDOUT_SAVE or die "CheckLib: $! restoring STDOUT handle"; open STDERR, ">&" . fileno STDERR_SAVE or die "CheckLib: $! restoring STDERR handle"; return $rv; } =head1 PLATFORMS SUPPORTED You must have a C compiler installed. We check for C<$Config{cc}>, both literally as it is in Config.pm and also in the $PATH. It has been tested with varying degrees on rigourousness on: =over =item gcc (on Linux, *BSD, Mac OS X, Solaris, Cygwin) =item Sun's compiler tools on Solaris =item IBM's tools on AIX =item SGI's tools on Irix 6.5 =item Microsoft's tools on Windows =item MinGW on Windows (with Strawberry Perl) =item Borland's tools on Windows =item QNX =back =head1 WARNINGS, BUGS and FEEDBACK This is a very early release intended primarily for feedback from people who have discussed it. The interface may change and it has not been adequately tested. Feedback is most welcome, including constructive criticism. Bug reports should be made using L or by email. When submitting a bug report, please include the output from running: perl -V perl -MDevel::CheckLib -e0 =head1 SEE ALSO L L =head1 AUTHORS David Cantrell Edavid@cantrell.org.ukE David Golden Edagolden@cpan.orgE Yasuhiro Matsumoto Emattn@cpan.orgE Thanks to the cpan-testers-discuss mailing list for prompting us to write it in the first place; to Chris Williams for help with Borland support; to Tony Cook for help with Microsoft compiler command-line options =head1 COPYRIGHT and LICENCE Copyright 2007 David Cantrell. Portions copyright 2007 David Golden. This module is free-as-in-speech software, and may be used, distributed, and modified under the same conditions as perl itself. =head1 CONSPIRACY This module is also free-as-in-mason software. =cut 1; Math-BigInt-GMP-1.37/INSTALL0000644005434300244210000000257611523750116015131 0ustar OSPJADomain UsersModule to replace Math::BigInt's core math routines by using Math::GMP. This package contains a replacement (drop-in) module for Math::BigInt's core, Math::BigInt::Calc.pm. It needs the new versions of Math::BigInt and Math::BigFloat as they are from Perl 5.7.x onwards. You need to install the Gnu MP library aka libgmp to compile this module. INSTALL ======= How to install: perl Makefile.PL make make test make install If you have trouble compiling this package because the GMP library is installed in a non-standard location, try to pass the INC and LIBS arguments to Makefile.PL with the appropriate information. Here is an example: perl Makefile.PL\ INC="-I/apps/perl588/site/gmp-4.2.1/include"\ LIBS="-L/apps/perl588/site/gmp-4.2.1/lib -lgmp" USAGE ===== To use it, replace: use Math::BigInt; with this: use Math::BigInt lib => 'GMP'; Since Math::BigInt will fallback to a pure-perl implementation, it is safe to always use lib => 'GMP'. Please read the documentation under PERFORMANCE in Math::BigInt on when to use this module and when not. More information including HTMLified help and preliminary benchmark results are available under: http://bloodgate.com/perl/ Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! Tels Math-BigInt-GMP-1.37/lib/0000755005434300244210000000000011630745101014631 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/lib/Math/0000755005434300244210000000000011630745101015522 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/lib/Math/BigInt/0000755005434300244210000000000011630745101016676 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/lib/Math/BigInt/GMP.pm0000644005434300244210000001234411630700422017660 0ustar OSPJADomain Users############################################################################### # core math lib for BigInt, representing big numbers by the GMP library package Math::BigInt::GMP; use strict; use 5.006002; # use warnings; # dont use warnings for older Perls use vars qw/$VERSION/; $VERSION = '1.37'; use XSLoader; XSLoader::load "Math::BigInt::GMP", $VERSION; sub import { } # catch and throw away sub api_version() { 2; } ############################################################################### # Routines not present here are in GMP.xs ############################################################################## # Return the nth digit, negative values count backward. sub _digit { my ($c, $x, $n) = @_; my $str = _str($c, $x); $n ++; substr($str , -$n, 1); } # Return a Perl numerical scalar. sub _num { my ($c, $x) = @_; return 0 + _str($c, $x); } # Return binomial coefficient (n over k). The code is based on _nok() in # Math::BigInt::Calc. sub _nok { # Return binomial coefficient (n over k). # Given refs to arrays, return ref to array. # First input argument is modified. my ($c, $n, $k) = @_; # If k > n/2, or, equivalently, 2*k > n, compute nok(n, k) as # nok(n, n-k), to minimize the number if iterations in the loop. { my $twok = _mul($c, _two($c), _copy($c, $k)); # 2 * k if (_acmp($c, $twok, $n) > 0) { # if 2*k > n $k = _sub($c, _copy($c, $n), $k); # k = n - k } } # Example: # # / 7 \ 7! 1*2*3*4 * 5*6*7 5 * 6 * 7 6 7 # | | = --------- = --------------- = --------- = 5 * - * - # \ 3 / (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3 2 3 if (_is_zero($c, $k)) { $n = _one($c); return $n; } # Make a copy of the original n, since we'll be modifing n in-place. my $n_orig = _copy($c, $n); # n = 5, f = 6, d = 2 (cf. example above) _sub($c, $n, $k); _inc($c, $n); my $f = _copy($c, $n); _inc($c, $f); my $d = _two($c); # while f <= n (the original n, that is) ... while (_acmp($c, $f, $n_orig) <= 0) { # n = (n * f / d) == 5 * 6 / 2 (cf. example above) _mul($c, $n, $f); _div($c, $n, $d); # f = 7, d = 3 (cf. example above) _inc($c, $f); _inc($c, $d); } return $n; } ############################################################################### # routine to test internal state for corruptions sub _check { # no checks yet, pull it out from the test suite my ($x) = $_[1]; return "$x is not a reference to Math::BigInt::GMP" if ref($x) ne 'Math::BigInt::GMP'; 0; } sub _log_int { my ($c,$x,$base) = @_; # X == 0 => NaN return if _is_zero($c,$x); $base = _new($c,2) unless defined $base; $base = _new($c,$base) unless ref $base; # BASE 0 or 1 => NaN return if (_is_zero($c, $base) || _is_one($c, $base)); my $cmp = _acmp($c,$x,$base); # X == BASE => 1 if ($cmp == 0) { # return one return (_one($c), 1); } # X < BASE if ($cmp < 0) { return (_zero($c),undef); } # Compute a guess for the result based on: # $guess = int ( length_in_base_10(X) / ( log(base) / log(10) ) ) my $len = _alen($c,$x); my $log = log( _str($c,$base) ) / log(10); # calculate now a guess based on the values obtained above: my $x_org = _copy($c,$x); # keep the reference to $x, modifying it in place _set($c, $x, int($len / $log) - 1); my $trial = _pow ($c, _copy($c, $base), $x); my $a = _acmp($c,$trial,$x_org); if ($a == 0) { return ($x,1); } elsif ($a > 0) { # too big, shouldn't happen _div($c,$trial,$base); _dec($c, $x); } # find the real result by going forward: my $base_mul = _mul($c, _copy($c,$base), $base); my $two = _two($c); while (($a = _acmp($c, $trial, $x_org)) < 0) { _mul($c,$trial,$base_mul); _add($c, $x, $two); } my $exact = 1; if ($a > 0) { # overstepped the result _dec($c, $x); _div($c,$trial,$base); $a = _acmp($c,$trial,$x_org); if ($a > 0) { _dec($c, $x); } $exact = 0 if $a != 0; } ($x,$exact); } sub STORABLE_freeze { my ($self, $cloning) = @_; return Math::BigInt::GMP->_str($self); } sub STORABLE_thaw { my ($self, $cloning, $serialized) = @_; Math::BigInt::GMP->_new_attach($self, $serialized); return $self; } 1; __END__ =pod =head1 NAME Math::BigInt::GMP - Use the GMP library for Math::BigInt routines =head1 SYNOPSIS Provides support for big integer calculations by means of the GMP c-library. Math::BigInt::GMP now no longer uses Math::GMP, but provides it's own XS layer to access the GMP c-library. This cut's out another (perl sub routine) layer and also reduces the memory footprint by not loading Math::GMP and Carp at all. =head1 LICENSE This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Tels Ehttp://bloodgate.com/E in 2001-2007. Thanx to Chip Turner for providing Math::GMP, which was inspiring my work. =head1 SEE ALSO L, L, L, L. =cut Math-BigInt-GMP-1.37/LICENSE0000644005434300244210000000021311523750103015063 0ustar OSPJADomain UsersThis program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. Tels Math-BigInt-GMP-1.37/Makefile.PL0000644005434300244210000000232611630705726016051 0ustar OSPJADomain Usersuse ExtUtils::MakeMaker; use lib 'inc'; # load our bundled version of Devel::CheckLib use Devel::CheckLib; #printf "Your OS is [%s]!\n---\n", $Config::Config{'osname'}; ### for testing purpose only if (($Config::Config{'osname'} eq 'darwin') &! (join (' ', @ARGV) =~ /LDDLFLAGS/)) { ### reads pre-existing LDDLFLAGS for a darwin system as defined in ### /System/Library/Perl/x.x.x/darwin-thread-multi-2level/Config.pm ### where x.x.x is the perl version, which is 5.8.1 for MacOS X 10.3, ### and appends ' -read_only_relocs suppress' ### default behavior if LDDLFLAGS is defined push @ARGV, sprintf "LDDLFLAGS=%s -read_only_relocs suppress", $Config::Config{'lddlflags'}; } check_lib_or_exit(lib => 'gmp', header => 'gmp.h', @ARGV); WriteMakefile ( 'NAME' => 'Math::BigInt::GMP', 'AUTHOR' => 'Tels', 'VERSION_FROM' => 'lib/Math/BigInt/GMP.pm', 'LICENSE' => 'perl', 'INSTALLDIRS' => 'site', 'ABSTRACT_FROM' => 'lib/Math/BigInt/GMP.pm', 'PREREQ_PM' => { Math::BigInt => 1.997, XSLoader => 0.02, }, 'LIBS' => ['-lgmp'], 'SIGN' => 1, ); Math-BigInt-GMP-1.37/MANIFEST0000644005434300244210000000115211630745105015217 0ustar OSPJADomain UsersBUGS build/leak.pl build/leaktest build/README CHANGES CREDITS GMP.xs inc/Devel/CheckLib.pm INSTALL lib/Math/BigInt/GMP.pm LICENSE Makefile.PL MANIFEST This list of files MANIFEST.SKIP README t/00sig.t t/01load.t t/02pod.t t/03podcov.t t/bigfltpm.inc t/bigfltpm.t t/bigintg.t t/bigintpm.inc t/bigintpm.t t/biglog.t t/bigroot.t t/storable.t t/threads.t TODO typemap META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) SIGNATURE Public-key signature (added by MakeMaker) Math-BigInt-GMP-1.37/MANIFEST.SKIP0000644005434300244210000000024311630706643015770 0ustar OSPJADomain Users.*\.tar\.gz ^blib.* ^\w+\.(html|txt|png|dot|pl|svg|old|bak|org) ^GMP.(o|bs|c) ^Makefile\z ^Makefile.(old|bak)\z .*\.patch\z ^MYMETA\.(yml|json)\z pm_to_blib \.git Math-BigInt-GMP-1.37/META.json0000644005434300244210000000160711630745104015513 0ustar OSPJADomain Users{ "abstract" : "Use the GMP library for Math::BigInt routines", "author" : [ "Tels" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.59, CPAN::Meta::Converter version 2.112150", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Math-BigInt-GMP", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : 0 } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : 0 } }, "runtime" : { "requires" : { "Math::BigInt" : "1.997", "XSLoader" : "0.02" } } }, "release_status" : "stable", "version" : "1.37" } Math-BigInt-GMP-1.37/META.yml0000644005434300244210000000076511630745102015345 0ustar OSPJADomain Users--- abstract: 'Use the GMP library for Math::BigInt routines' author: - Tels build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.59, CPAN::Meta::Converter version 2.112150' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Math-BigInt-GMP no_index: directory: - t - inc requires: Math::BigInt: 1.997 XSLoader: 0.02 version: 1.37 Math-BigInt-GMP-1.37/README0000644005434300244210000000361311523750106014750 0ustar OSPJADomain UsersModule to replace Math::BigInt's core math routines by using Math::GMP. (C) 2001 by TELS. All rights reserved. This package contains a replacement (drop-in) module for Math::BigInt's core, Math::BigInt::Calc.pm. It needs the new versions of Math::BigInt and Math::BigFloat as they are from Perl 5.7.x onwards. You need to install the Gnu MP library aka libgmp to compile this module. How to install (replace the version below with the current one): tar -xzf Math-BigInt-GMP-1.12.tar.gz cpansign --verify If the signature does not verify ok, you might to install Module::Signature and get my key from . If the signature still does not verify okay, notify me. DO NO INSTALL this package when the signature is BAD - your system might get compromised! If the signature is good, do: perl Makefile.PL make make test and then as root: make install To use this module, replace: use Math::BigInt; with this: use Math::BigInt lib => 'GMP'; or alternatively something like: use Math::BigInt lib => 'GMP,Pari,BitVect'; Please read the documentation under PERFORMANCE in Math::BigInt on when to use this module and when not. As of v1.10 and Math::BigInt v1.64/v1.64, using "lib => 'GMP'" will actually reduce the memory consumption of your program, and thanx to the fact that we no longer use Math::GMP but have our own XS code, almost all operations should be faster than just using Calc (the default pure-perl library used in Math::BigInt). So, the following: use Math::BigInt lib => 'GMP'; can be heartily recommended. More information including HTMLified help and preliminary benchmark results are available under: http://bloodgate.com/perl/bigint/ Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! (c) Tels 2001-2003 Math-BigInt-GMP-1.37/SIGNATURE0000644005434300244210000000500511630745112015351 0ustar OSPJADomain UsersThis file contains message digests of all files listed in MANIFEST, signed via the Module::Signature module, version 0.68. To verify the content in this distribution, first make sure you have Module::Signature installed, then type: % cpansign -v It will check each file's integrity, as well as the signature's validity. If "==> Signature verified OK! <==" is not displayed, the distribution may already have been compromised, and you should not run its Makefile.PL or Build.PL. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 SHA1 70d6187d0152848c922dc4360fa6dd3a3dc35c62 BUGS SHA1 1c38b0790580a2e2239404dd7d5de0b8ce415f11 CHANGES SHA1 dda5ca4f413031e9efcaa1600461d5e2adaa3a40 CREDITS SHA1 d7497d6d105042817c1734585be04ad2ebec4db2 GMP.xs SHA1 d6b7be7fb558f2df93e6bc55148bba35cae22ce4 INSTALL SHA1 d6a6c30ee6d9ba6b9afab8bbf6a25e1b23c744e0 LICENSE SHA1 f1f5d7799d2a10004d9fde9e929edaca038b8c6b MANIFEST SHA1 411ab4f05c252f85f12f12e087bae0adc5ba0aad MANIFEST.SKIP SHA1 95a51ac44107896279b27d07eb571553f3c5a457 META.json SHA1 f8705c7b74812ddd94b4056fc5bad153d8d8273f META.yml SHA1 c1e61286ff1f620f3da7fc7d06fdc4f6ce105546 Makefile.PL SHA1 ddef2225fa80a87f3138f23cb7fdbc8468c1f58f README SHA1 6c7207c83d636868d3d1f1fc42f3f9e5897cbe85 TODO SHA1 fd48d0d8750eb949e485d8136b5b424fe73e9775 build/README SHA1 7bcc4113830721ad6e37a1ea79df94a6987c836d build/leak.pl SHA1 ac25bda8a6eb9058a9e42a8943c3e11b9fed88dc build/leaktest SHA1 5bad87980fc59ecb29c9afe0719c48ad32758d63 inc/Devel/CheckLib.pm SHA1 06320330b1c5212c4b733c24f12d5594ab35dbe1 lib/Math/BigInt/GMP.pm SHA1 6e9557e746e881ab1568cdcec17ff3c4f1508502 t/00sig.t SHA1 ab94a8c86b2b8fda2e02f9e3de43dff6186e65d3 t/01load.t SHA1 02ef05af53cb7378452590324bb21dfe61f44069 t/02pod.t SHA1 ada3fcae2f9313cc97e0b999b13b30dac9a3deda t/03podcov.t SHA1 d05514d6cae3afa4feb983d5467eaf9422aa546c t/bigfltpm.inc SHA1 a8f364fea5e2993f5ae7bd3f8463024175d33e24 t/bigfltpm.t SHA1 26c3ca060f6b7474ad8b2db3c1bae2b98e13adfd t/bigintg.t SHA1 845e7daa3c6b2463a6fdc9218044975801547bb8 t/bigintpm.inc SHA1 5c7e31a73f1827d08118f96cf31d5d4e792ab8c0 t/bigintpm.t SHA1 5bdf82ef7085b97caa496bfc71ab1fbfe48ef9e8 t/biglog.t SHA1 da260b6e02b220868fc7b4c0f87569299402fbf7 t/bigroot.t SHA1 f1bcab94173a57861fcc40ac90eb72f64aafea7f t/storable.t SHA1 e489ec79ce64d0d943e291a3eaa654298e6e49ab t/threads.t SHA1 20cf43acc1a728d0ee8245b106937a2a97900266 typemap -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) iEYEARECAAYFAk5jykUACgkQVQvyyU1bchpbUQCglrXtBTDqJHOcg4jNhANCddpi SRMAoNAV0CKT1a3JdH7AdSkh4vixU8Jw =HATQ -----END PGP SIGNATURE----- Math-BigInt-GMP-1.37/t/0000755005434300244210000000000011630745101014326 5ustar OSPJADomain UsersMath-BigInt-GMP-1.37/t/00sig.t0000644005434300244210000000176011523761562015453 0ustar OSPJADomain Users#!/usr/bin/perl use strict; # restrict unsafe constructs use Test::More; if (!$ENV{TEST_SIGNATURE}) { plan skip_all => "Set the environment variable TEST_SIGNATURE to enable this test."; } elsif (!eval { require Module::Signature; 1 }) { plan skip_all => "Next time around, consider installing Module::Signature, ". "so you can verify the integrity of this distribution."; } elsif (!-e 'SIGNATURE') { plan skip_all => "SIGNATURE not found"; } elsif (!-s 'SIGNATURE') { plan skip_all => "SIGNATURE file empty"; } elsif (!eval { require Socket; Socket::inet_aton('pool.sks-keyservers.net') }) { plan skip_all => "Cannot connect to the keyserver to check module ". "signature"; } else { plan tests => 1; } my $ret = Module::Signature::verify(); SKIP: { skip "Module::Signature cannot verify", 1 if $ret eq Module::Signature::CANNOT_VERIFY(); cmp_ok $ret, '==', Module::Signature::SIGNATURE_OK(), "Valid signature"; } Math-BigInt-GMP-1.37/t/01load.t0000644005434300244210000000054111524240264015575 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; # restrict unsafe constructs use Test::More tests => 2; BEGIN { use_ok('Math::BigInt::GMP'); use_ok('Math::BigInt'); # Math::BigInt is required for the tests }; diag("Testing Math::BigInt::GMP $Math::BigInt::GMP::VERSION, Perl $], $^X"); diag(" with Math::BigInt $Math::BigInt::VERSION"); Math-BigInt-GMP-1.37/t/02pod.t0000644005434300244210000000041611523761632015450 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; # restrict unsafe constructs use Test::More; # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok(); Math-BigInt-GMP-1.37/t/03podcov.t0000644005434300244210000000143311523761636016165 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; # restrict unsafe constructs use Test::More; # Ensure a recent version of Test::Pod::Coverage my $min_tpc = 1.08; eval "use Test::Pod::Coverage $min_tpc"; plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" if $@; # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, # but older versions don't recognize some common documentation styles my $min_pc = 0.18; eval "use Pod::Coverage $min_pc"; plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" if $@; my $trustme = { trustme => [ 'api_version', 'STORABLE_freeze', 'STORABLE_thaw' ], coverage_class => 'Pod::Coverage::CountParents', }; all_pod_coverage_ok($trustme, "All our Math::BigInt::GMP are covered"); Math-BigInt-GMP-1.37/t/bigfltpm.inc0000644005434300244210000010741511630344241016635 0ustar OSPJADomain Users#include this file into another test for subclass testing... is ($class->config()->{lib},$CL); use strict; my $z; while () { $_ =~ s/[\n\r]//g; # remove newlines $_ =~ s/#.*$//; # remove comments $_ =~ s/\s+$//; # trailing spaces next if /^$/; # skip empty lines & comments if (s/^&//) { $f = $_; } elsif (/^\$/) { $setup = $_; $setup =~ s/\$/\$${class}::/g; # round_mode, div_scale #print "\$setup== $setup\n"; } else { if (m|^(.*?):(/.+)$|) { $ans = $2; @args = split(/:/,$1,99); } else { @args = split(/:/,$_,99); $ans = pop(@args); } $try = "\$x = $class->new(\"$args[0]\");"; if ($f eq "fnorm") { $try .= "\$x;"; } elsif ($f eq "finf") { $try .= "\$x->finf('$args[1]');"; } elsif ($f eq "is_inf") { $try .= "\$x->is_inf('$args[1]');"; } elsif ($f eq "fone") { $try .= "\$x->bone('$args[1]');"; } elsif ($f eq "fstr") { $try .= "\$x->accuracy($args[1]); \$x->precision($args[2]);"; $try .= '$x->fstr();'; } elsif ($f eq "parts") { # ->bstr() to see if an object is returned $try .= '($a,$b) = $x->parts(); $a = $a->bstr(); $b = $b->bstr();'; $try .= '"$a $b";'; } elsif ($f eq "exponent") { # ->bstr() to see if an object is returned $try .= '$x->exponent()->bstr();'; } elsif ($f eq "mantissa") { # ->bstr() to see if an object is returned $try .= '$x->mantissa()->bstr();'; } elsif ($f =~ /^(numify|length|as_number|as_hex|as_bin)$/) { $try .= "\$x->$f();"; # some unary ops (test the fxxx form, since that is done by AUTOLOAD) } elsif ($f =~ /^f(nan|sstr|neg|floor|ceil|abs)$/) { $try .= "\$x->f$1();"; # some is_xxx test function } elsif ($f =~ /^is_(zero|one|negative|positive|odd|even|nan|int)$/) { $try .= "\$x->$f();"; } elsif ($f eq "bpi") { $try .= '$class->bpi($x);'; } elsif ($f eq "finc") { $try .= '++$x;'; } elsif ($f eq "fdec") { $try .= '--$x;'; }elsif ($f eq "fround") { $try .= "$setup; \$x->fround($args[1]);"; } elsif ($f eq "ffround") { $try .= "$setup; \$x->ffround($args[1]);"; } elsif ($f eq "fsqrt") { $try .= "$setup; \$x->fsqrt();"; } elsif ($f eq "ffac") { $try .= "$setup; \$x->ffac();"; } elsif ($f eq "flog") { if (defined $args[1] && $args[1] ne '') { $try .= "\$y = $class->new($args[1]);"; $try .= "$setup; \$x->flog(\$y);"; } else { $try .= "$setup; \$x->flog();"; } } else { $try .= "\$y = $class->new(\"$args[1]\");"; if ($f eq "bgcd") { if (defined $args[2]) { $try .= " \$z = $class->new(\"$args[2]\"); "; } $try .= "$class\::bgcd(\$x, \$y"; $try .= ", \$z" if (defined $args[2]); $try .= " );"; } elsif ($f eq "blcm") { if (defined $args[2]) { $try .= " \$z = $class->new(\"$args[2]\"); "; } $try .= "$class\::blcm(\$x, \$y"; $try .= ", \$z" if (defined $args[2]); $try .= " );"; } elsif ($f eq "fcmp") { $try .= '$x->fcmp($y);'; } elsif ($f eq "facmp") { $try .= '$x->facmp($y);'; } elsif ($f eq "fpow") { $try .= '$x ** $y;'; } elsif ($f eq "bnok") { $try .= '$x->bnok($y);'; } elsif ($f eq "bcos") { $try .= '$x->bcos($y);'; } elsif ($f eq "bsin") { $try .= '$x->bsin($y);'; } elsif ($f eq "batan") { $try .= '$x->batan($y);'; } elsif ($f eq "froot") { $try .= "$setup; \$x->froot(\$y);"; } elsif ($f eq "fadd") { $try .= '$x + $y;'; } elsif ($f eq "fsub") { $try .= '$x - $y;'; } elsif ($f eq "fmul") { $try .= '$x * $y;'; } elsif ($f eq "fdiv") { $try .= "$setup; \$x / \$y;"; } elsif ($f eq "fdiv-list") { $try .= "$setup; join(',',\$x->fdiv(\$y));"; } elsif ($f eq "frsft") { $try .= '$x >> $y;'; } elsif ($f eq "flsft") { $try .= '$x << $y;'; } elsif ($f eq "fmod") { $try .= '$x % $y;'; } else { # Functions with three arguments $try .= "\$z = $class->new(\"$args[2]\");"; if( $f eq "bmodpow") { $try .= '$x->bmodpow($y,$z);'; } elsif ($f eq "bmuladd"){ $try .= '$x->bmuladd($y,$z);'; } elsif ($f eq "batan2"){ $try .= '$x->batan2($y,$z);'; } else { warn "Unknown op '$f'"; } } } # print "# Trying: '$try'\n"; $ans1 = eval $try; print "# Error: $@\n" if $@; if ($ans =~ m|^/(.*)$|) { my $pat = $1; if ($ans1 =~ /$pat/) { is (1,1); } else { print "# '$try' expected: /$pat/ got: '$ans1'\n" if !is (1,0); } } else { if ($ans eq "") { is ($ans1, undef); } else { print "# Tried: '$try'\n" if !is ($ans1, $ans); if (ref($ans1) eq "$class") { # float numbers are normalized (for now), so mantissa shouldn't have # trailing zeros #print $ans1->_trailing_zeros(),"\n"; print "# Has trailing zeros after '$try'\n" if !is ($CL->_zeros( $ans1->{_m}), 0); } } } # end pattern or string } } # end while # check whether $class->new( Math::BigInt->new()) destroys it # ($y == 12 in this case) $x = Math::BigInt->new(1200); $y = $class->new($x); is ($y,1200); is ($x,1200); ############################################################################### # Really huge, big, ultra-mega-biggy-monster exponents # Technically, the exponents should not be limited (they are BigInts), but # practically there are a few places were they are limited to a Perl scalar. # This is sometimes for speed, sometimes because otherwise the number wouldn't # fit into your memory (just think of 1e123456789012345678901234567890 + 1!) # anyway. We don't test everything here, but let's make sure it just basically # works. my $monster = '1e1234567890123456789012345678901234567890'; # new and exponent is ($class->new($monster)->bsstr(), '1e+1234567890123456789012345678901234567890'); is ($class->new($monster)->exponent(), '1234567890123456789012345678901234567890'); # cmp is ($class->new($monster) > 0,1); # sub/mul is ($class->new($monster)->bsub( $monster),0); is ($class->new($monster)->bmul(2)->bsstr(), '2e+1234567890123456789012345678901234567890'); # mantissa $monster = '1234567890123456789012345678901234567890e2'; is ($class->new($monster)->mantissa(), '123456789012345678901234567890123456789'); ############################################################################### # zero,inf,one,nan $x = $class->new(2); $x->fzero(); is ($x->{_a}, undef); is ($x->{_p}, undef); $x = $class->new(2); $x->finf(); is ($x->{_a}, undef); is ($x->{_p}, undef); $x = $class->new(2); $x->fone(); is ($x->{_a}, undef); is ($x->{_p}, undef); $x = $class->new(2); $x->fnan(); is ($x->{_a}, undef); is ($x->{_p}, undef); ############################################################################### # bone/binf etc as plain calls (Lite failed them) is ($class->fzero(),0); is ($class->fone(),1); is ($class->fone('+'),1); is ($class->fone('-'),-1); is ($class->fnan(),'NaN'); is ($class->finf(),'inf'); is ($class->finf('+'),'inf'); is ($class->finf('-'),'-inf'); is ($class->finf('-inf'),'-inf'); $class->accuracy(undef); $class->precision(undef); # reset ############################################################################### # bug in bsstr()/numify() showed up in after-rounding in bdiv() $x = $class->new('0.008'); $y = $class->new(2); $x->bdiv(3,$y); is ($x,'0.0027'); ############################################################################### # Verify that numify() returns a normalized value, and underflows and # overflows when given "extreme" values. like($class->new("12345e67")->numify(), qr/^1\.2345e\+?0*71$/); like($class->new("1e-9999")->numify(), qr/^\+?0$/); # underflow unlike($class->new("1e9999")->numify(), qr/^1(\.0*)?e\+?9+$/); # overflow ############################################################################### # fsqrt() with set global A/P or A/P enabled on $x, also a test whether fsqrt() # correctly modifies $x $x = $class->new(12); $class->precision(-2); $x->fsqrt(); is ($x,'3.46'); $class->precision(undef); $x = $class->new(12); $class->precision(0); $x->fsqrt(); is ($x,'3'); $class->precision(-3); $x = $class->new(12); $x->fsqrt(); is ($x,'3.464'); { no strict 'refs'; # A and P set => NaN ${${class}.'::accuracy'} = 4; $x = $class->new(12); $x->fsqrt(3); is ($x,'NaN'); # supplied arg overrides set global $class->precision(undef); $x = $class->new(12); $x->fsqrt(3); is ($x,'3.46'); $class->accuracy(undef); $class->precision(undef); # reset for further tests } ############################################################################# # can we call objectify (broken until v1.52) { no strict; $try = '@args' . " = $class" . "::objectify(2,$class,4,5);".'join(" ",@args);'; $ans = eval $try; is ($ans,"$class 4 5"); } ############################################################################# # is_one('-') (broken until v1.64) is ($class->new(-1)->is_one(),0); is ($class->new(-1)->is_one('-'),1); ############################################################################# # bug 1/0.5 leaving 2e-0 instead of 2e0 is ($class->new(1)->fdiv('0.5')->bsstr(),'2e+0'); ############################################################################### # [perl #30609] bug with $x -= $x not being 0, but 2*$x $x = $class->new(3); $x -= $x; is ($x, 0); $x = $class->new(-3); $x -= $x; is ($x, 0); $x = $class->new(3); $x += $x; is ($x, 6); $x = $class->new(-3); $x += $x; is ($x, -6); $x = $class->new('NaN'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('inf'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('-inf'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('NaN'); $x += $x; is ($x->is_nan(), 1); $x = $class->new('inf'); $x += $x; is ($x->is_inf(), 1); $x = $class->new('-inf'); $x += $x; is ($x->is_inf('-'), 1); $x = $class->new('3.14'); $x -= $x; is ($x, 0); $x = $class->new('-3.14'); $x -= $x; is ($x, 0); $x = $class->new('3.14'); $x += $x; is ($x, '6.28'); $x = $class->new('-3.14'); $x += $x; is ($x, '-6.28'); $x = $class->new('3.14'); $x *= $x; is ($x, '9.8596'); $x = $class->new('-3.14'); $x *= $x; is ($x, '9.8596'); $x = $class->new('3.14'); $x /= $x; is ($x, '1'); $x = $class->new('-3.14'); $x /= $x; is ($x, '1'); $x = $class->new('3.14'); $x %= $x; is ($x, '0'); $x = $class->new('-3.14'); $x %= $x; is ($x, '0'); ############################################################################### # the following two were reported by "kenny" via hotmail.com: #perl -MMath::BigFloat -wle 'print Math::BigFloat->new(0)->bpow(".1")' #Use of uninitialized value in numeric le (<=) at BigFloat.pm line 1851. $x = $class->new(0); $y = $class->new('0.1'); is ($x ** $y, 0, 'no warnings and zero result'); #perl -MMath::BigFloat -lwe 'print Math::BigFloat->new(".222222222222222222222222222222222222222222")->bceil()' #Use of uninitialized value in numeric le (<=) at BigFloat.pm line 1851. $x = $class->new(".222222222222222222222222222222222222222222"); is ($x->bceil(), 1, 'no warnings and one as result'); ############################################################################### # test **=, <<=, >>= # ((2^148)-1)/17 $x = $class->new(2); $x **= 148; $x++; $x->bdiv(17, 60)->bfloor(); $x->accuracy(undef); is ($x,"20988936657440586486151264256610222593863921"); is ($x->length(),length "20988936657440586486151264256610222593863921"); $x = $class->new('2'); my $y = $class->new('18'); is ($x <<= $y, 2 << 18); is ($x, 2 << 18); is ($x >>= $y, 2); is ($x, 2); $x = $class->new('2'); $y = $class->new('18.2'); $x <<= $y; # 2 * (2 ** 18.2); is ($x->copy()->bfround(-9), '602248.763144685'); is ($x >>= $y, 2); # 2 * (2 ** 18.2) / (2 ** 18.2) => 2 is ($x, 2); 1; # all done __DATA__ &bgcd inf:12:NaN -inf:12:NaN 12:inf:NaN 12:-inf:NaN inf:inf:NaN inf:-inf:NaN -inf:-inf:NaN abc:abc:NaN abc:+0:NaN +0:abc:NaN +0:+0:0 +0:+1:1 +1:+0:1 +1:+1:1 +2:+3:1 +3:+2:1 -3:+2:1 -3:-2:1 -144:-60:12 144:-60:12 144:60:12 100:625:25 4096:81:1 1034:804:2 27:90:56:1 27:90:54:9 &blcm abc:abc:NaN abc:+0:NaN +0:abc:NaN +0:+0:NaN +1:+0:0 +0:+1:0 +27:+90:270 +1034:+804:415668 $div_scale = 40; &bcos 1.2:10:0.3623577545 2.4:12:-0.737393715541 0:10:1 0:20:1 1:10:0.5403023059 1:12:0.540302305868 &bsin 1:10:0.8414709848 0:10:0 0:20:0 2.1:12:0.863209366649 1.2:13:0.9320390859672 0.2:13:0.1986693307951 3.2:12:-0.0583741434276 &batan NaN:10:NaN inf:14:1.5707963267949 -inf:14:-1.5707963267949 0.2:13:0.1973955598499 0.2:14:0.19739555984988 0:10:0 1:14:0.78539816339744 -1:14:-0.78539816339744 # test an argument X > 1 2:14:1.1071487177941 &batan2 NaN:1:10:NaN NaN:NaN:10:NaN 1:NaN:10:NaN inf:1:14:1.5707963267949 -inf:1:14:-1.5707963267949 0:-inf:14:3.1415926535898 -1:-inf:14:-3.1415926535898 1:-inf:14:3.1415926535898 0:inf:14:0 inf:-inf:14:2.3561944901923 -inf:-inf:14:-2.3561944901923 inf:+inf:14:0.7853981633974 -inf:+inf:14:-0.7853981633974 1:5:13:0.1973955598499 1:5:14:0.19739555984988 0:0:10:0 0:1:14:0 0:2:14:0 1:0:14:1.5707963267949 5:0:14:1.5707963267949 -1:0:11:-1.5707963268 -2:0:77:-1.5707963267948966192313216916397514420985846996875529104874722961539082031431 2:0:77:1.5707963267948966192313216916397514420985846996875529104874722961539082031431 -1:5:14:-0.19739555984988 1:5:14:0.19739555984988 -1:8:14:-0.12435499454676 1:8:14:0.12435499454676 -1:1:14:-0.78539816339744 # test an argument X > 1 and one X < 1 1:2:24:0.463647609000806116214256 2:1:14:1.1071487177941 -2:1:14:-1.1071487177941 &bpi 150:3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940813 77:3.1415926535897932384626433832795028841971693993751058209749445923078164062862 +0:3.141592653589793238462643383279502884197 11:3.1415926536 &bnok +inf:10:inf NaN:NaN:NaN NaN:1:NaN 1:NaN:NaN 1:1:1 # k > n 1:2:0 2:3:0 # k < 0 1:-2:0 # 7 over 3 = 35 7:3:35 7:6:7 100:90:17310309456440 100:95:75287520 2:0:1 7:0:1 2:1:2 &flog 0::NaN -1::NaN -2::NaN # base > 0, base != 1 2:-1:NaN 2:0:NaN 2:1:NaN # log(1) is always 1, regardless of $base 1::0 1:1:0 1:2:0 2::0.6931471805599453094172321214581765680755 2.718281828::0.9999999998311266953289851340574956564911 $div_scale = 20; 2.718281828::0.99999999983112669533 $div_scale = 15; 123::4.81218435537242 10::2.30258509299405 1000::6.90775527898214 100::4.60517018598809 2::0.693147180559945 3.1415::1.14470039286086 12345::9.42100640177928 0.001::-6.90775527898214 # bug until v1.71: 10:10:1 100:100:1 # reset for further tests $div_scale = 40; 1::0 &frsft NaNfrsft:2:NaN 0:2:0 1:1:0.5 2:1:1 4:1:2 123:1:61.5 32:3:4 &flsft NaNflsft:0:NaN 2:1:4 4:3:32 5:3:40 1:2:4 0:5:0 &fnorm 1:1 -0:0 fnormNaN:NaN +inf:inf -inf:-inf 123:123 -123.4567:-123.4567 # invalid inputs 1__2:NaN 1E1__2:NaN 11__2E2:NaN .2E-3.:NaN 1e3e4:NaN # strange, but valid .2E2:20 1.E3:1000 # some inputs that result in zero 0e0:0 +0e0:0 +0e+0:0 -0e+0:0 0e-0:0 -0e-0:0 +0e-0:0 000:0 00e2:0 00e02:0 000e002:0 000e1230:0 00e-3:0 00e+3:0 00e-03:0 00e+03:0 -000:0 -00e2:0 -00e02:0 -000e002:0 -000e1230:0 -00e-3:0 -00e+3:0 -00e-03:0 -00e+03:0 &as_number 0:0 1:1 1.2:1 2.345:2 -2:-2 -123.456:-123 -200:-200 -inf:-inf inf:inf NaN:NaN 71243225429896467497217836789578596379:71243225429896467497217836789578596379 # test for bug in brsft() not handling cases that return 0 0.000641:0 0.0006412:0 0.00064123:0 0.000641234:0 0.0006412345:0 0.00064123456:0 0.000641234567:0 0.0006412345678:0 0.00064123456789:0 0.1:0 0.01:0 0.001:0 0.0001:0 0.00001:0 0.000001:0 0.0000001:0 0.00000001:0 0.000000001:0 0.0000000001:0 0.00000000001:0 0.12345:0 0.123456:0 0.1234567:0 0.12345678:0 0.123456789:0 &finf 1:+:inf 2:-:-inf 3:abc:inf &as_hex +inf:inf -inf:-inf hexNaN:NaN 0:0x0 5:0x5 -5:-0x5 &as_bin +inf:inf -inf:-inf hexNaN:NaN 0:0b0 5:0b101 -5:-0b101 &numify # uses bsstr() so 5 => 5e+0 to be compatible w/ Perls output 0:0 +1:1 1234:1234 -5:-5 100:100 -100:-100 &fnan abc:NaN 2:NaN -2:NaN 0:NaN &fone 2:+:1 -2:-:-1 -2:+:1 2:-:-1 0::1 -2::1 abc::1 2:abc:1 &fsstr +inf:inf -inf:-inf abcfsstr:NaN -abcfsstr:NaN 1234.567:1234567e-3 123:123e+0 -5:-5e+0 -100:-1e+2 &fstr +inf:::inf -inf:::-inf abcfstr:::NaN 1234.567:9::1234.56700 1234.567::-6:1234.567000 12345:5::12345 0.001234:6::0.00123400 0.001234::-8:0.00123400 0:4::0 0::-4:0.0000 &fnorm inf:inf +inf:inf -inf:-inf +infinity:NaN +-inf:NaN abc:NaN 1 a:NaN 1bcd2:NaN 11111b:NaN +1z:NaN -1z:NaN 0e999:0 0e-999:0 -0e999:0 -0e-999:0 0:0 +0:0 +00:0 +0_0_0:0 000000_0000000_00000:0 -0:0 -0000:0 +1:1 +01:1 +001:1 +00000100000:100000 123456789:123456789 -1:-1 -01:-1 -001:-1 -123456789:-123456789 -00000100000:-100000 123.456a:NaN 123.456:123.456 0.01:0.01 .002:0.002 +.2:0.2 -0.0003:-0.0003 -.0000000004:-0.0000000004 123456E2:12345600 123456E-2:1234.56 -123456E2:-12345600 -123456E-2:-1234.56 1e1:10 2e-11:0.00000000002 # exercise _split .02e-1:0.002 000001:1 -00001:-1 -1:-1 000.01:0.01 -000.0023:-0.0023 1.1e1:11 -3e111:-3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -4e-1111:-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 &fpow NaN:1:NaN 1:NaN:NaN NaN:-1:NaN -1:NaN:NaN NaN:-21:NaN -21:NaN:NaN NaN:21:NaN 21:NaN:NaN 0:0:1 0:1:0 0:9:0 0:-2:inf 2:2:4 1:2:1 1:3:1 -1:2:1 -1:3:-1 123.456:2:15241.383936 2:-2:0.25 2:-3:0.125 128:-2:0.00006103515625 abc:123.456:NaN 123.456:abc:NaN +inf:123.45:inf -inf:123.45:-inf +inf:-123.45:inf -inf:-123.45:-inf -2:2:4 -2:3:-8 -2:4:16 -2:5:-32 -3:2:9 -3:3:-27 -3:4:81 -3:5:-243 # 2 ** 0.5 == sqrt(2) # 1.41..7 and not 1.4170 since fallback (bsqrt(9) is '3', not 3.0...0) 2:0.5:1.41421356237309504880168872420969807857 #2:0.2:1.148698354997035006798626946777927589444 #6:1.5:14.6969384566990685891837044482353483518 $div_scale = 20; #62.5:12.5:26447206647554886213592.3959144 $div_scale = 40; &fneg fnegNaN:NaN +inf:-inf -inf:inf +0:0 +1:-1 -1:1 +123456789:-123456789 -123456789:123456789 +123.456789:-123.456789 -123456.789:123456.789 &fabs fabsNaN:NaN +inf:inf -inf:inf +0:0 +1:1 -1:1 +123456789:123456789 -123456789:123456789 +123.456789:123.456789 -123456.789:123456.789 &fround $round_mode = "trunc" +inf:5:inf -inf:5:-inf 0:5:0 NaNfround:5:NaN +10123456789:5:10123000000 -10123456789:5:-10123000000 +10123456789.123:5:10123000000 -10123456789.123:5:-10123000000 +10123456789:9:10123456700 -10123456789:9:-10123456700 +101234500:6:101234000 -101234500:6:-101234000 $round_mode = "zero" +20123456789:5:20123000000 -20123456789:5:-20123000000 +20123456789.123:5:20123000000 -20123456789.123:5:-20123000000 +20123456789:9:20123456800 -20123456789:9:-20123456800 +201234500:6:201234000 -201234500:6:-201234000 $round_mode = "+inf" +30123456789:5:30123000000 -30123456789:5:-30123000000 +30123456789.123:5:30123000000 -30123456789.123:5:-30123000000 +30123456789:9:30123456800 -30123456789:9:-30123456800 +301234500:6:301235000 -301234500:6:-301234000 $round_mode = "-inf" +40123456789:5:40123000000 -40123456789:5:-40123000000 +40123456789.123:5:40123000000 -40123456789.123:5:-40123000000 +40123456789:9:40123456800 -40123456789:9:-40123456800 +401234500:6:401234000 -401234500:6:-401235000 $round_mode = "odd" +50123456789:5:50123000000 -50123456789:5:-50123000000 +50123456789.123:5:50123000000 -50123456789.123:5:-50123000000 +50123456789:9:50123456800 -50123456789:9:-50123456800 +501234500:6:501235000 -501234500:6:-501235000 $round_mode = "even" +60123456789:5:60123000000 -60123456789:5:-60123000000 +60123456789:9:60123456800 -60123456789:9:-60123456800 +601234500:6:601234000 -601234500:6:-601234000 +60123456789.0123:5:60123000000 -60123456789.0123:5:-60123000000 $round_mode = "common" +60123456789:5:60123000000 -60123456789:5:-60123000000 +60123456789:6:60123500000 -60123456789:6:-60123500000 +60123456789:9:60123456800 -60123456789:9:-60123456800 +601234500:6:601235000 -601234500:6:-601235000 +601234400:6:601234000 -601234400:6:-601234000 +601234600:6:601235000 -601234600:6:-601235000 +601234300:6:601234000 +60123456789.0123:5:60123000000 -60123456789.0123:5:-60123000000 &ffround $round_mode = "trunc" +inf:5:inf -inf:5:-inf 0:5:0 NaNffround:5:NaN +1.23:-1:1.2 +1.234:-1:1.2 +1.2345:-1:1.2 +1.23:-2:1.23 +1.234:-2:1.23 +1.2345:-2:1.23 +1.23:-3:1.230 +1.234:-3:1.234 +1.2345:-3:1.234 -1.23:-1:-1.2 +1.27:-1:1.2 -1.27:-1:-1.2 +1.25:-1:1.2 -1.25:-1:-1.2 +1.35:-1:1.3 -1.35:-1:-1.3 -0.0061234567890:-1:0.0 -0.0061:-1:0.0 -0.00612:-1:0.0 -0.00612:-2:0.00 -0.006:-1:0.0 -0.006:-2:0.00 -0.0006:-2:0.00 -0.0006:-3:0.000 -0.0065:-3:/-0\.006|-6e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:0 0.51:0:0 0.41:0:0 $round_mode = "zero" +2.23:-1:/2.2(?:0{5}\d+)? -2.23:-1:/-2.2(?:0{5}\d+)? +2.27:-1:/2.(?:3|29{5}\d+) -2.27:-1:/-2.(?:3|29{5}\d+) +2.25:-1:/2.2(?:0{5}\d+)? -2.25:-1:/-2.2(?:0{5}\d+)? +2.35:-1:/2.(?:3|29{5}\d+) -2.35:-1:/-2.(?:3|29{5}\d+) -0.0065:-1:0.0 -0.0065:-2:/-0\.01|-1e-02 -0.0065:-3:/-0\.006|-6e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:0 0.51:0:1 0.41:0:0 $round_mode = "+inf" +3.23:-1:/3.2(?:0{5}\d+)? -3.23:-1:/-3.2(?:0{5}\d+)? +3.27:-1:/3.(?:3|29{5}\d+) -3.27:-1:/-3.(?:3|29{5}\d+) +3.25:-1:/3.(?:3|29{5}\d+) -3.25:-1:/-3.2(?:0{5}\d+)? +3.35:-1:/3.(?:4|39{5}\d+) -3.35:-1:/-3.(?:3|29{5}\d+) -0.0065:-1:0.0 -0.0065:-2:/-0\.01|-1e-02 -0.0065:-3:/-0\.006|-6e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:1 0.51:0:1 0.41:0:0 $round_mode = "-inf" +4.23:-1:/4.2(?:0{5}\d+)? -4.23:-1:/-4.2(?:0{5}\d+)? +4.27:-1:/4.(?:3|29{5}\d+) -4.27:-1:/-4.(?:3|29{5}\d+) +4.25:-1:/4.2(?:0{5}\d+)? -4.25:-1:/-4.(?:3|29{5}\d+) +4.35:-1:/4.(?:3|29{5}\d+) -4.35:-1:/-4.(?:4|39{5}\d+) -0.0065:-1:0.0 -0.0065:-2:/-0\.01|-1e-02 -0.0065:-3:/-0\.007|-7e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:0 0.51:0:1 0.41:0:0 $round_mode = "odd" +5.23:-1:/5.2(?:0{5}\d+)? -5.23:-1:/-5.2(?:0{5}\d+)? +5.27:-1:/5.(?:3|29{5}\d+) -5.27:-1:/-5.(?:3|29{5}\d+) +5.25:-1:/5.(?:3|29{5}\d+) -5.25:-1:/-5.(?:3|29{5}\d+) +5.35:-1:/5.(?:3|29{5}\d+) -5.35:-1:/-5.(?:3|29{5}\d+) -0.0065:-1:0.0 -0.0065:-2:/-0\.01|-1e-02 -0.0065:-3:/-0\.007|-7e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:1 0.51:0:1 0.41:0:0 $round_mode = "even" +6.23:-1:/6.2(?:0{5}\d+)? -6.23:-1:/-6.2(?:0{5}\d+)? +6.27:-1:/6.(?:3|29{5}\d+) -6.27:-1:/-6.(?:3|29{5}\d+) +6.25:-1:/6.(?:2(?:0{5}\d+)?|29{5}\d+) -6.25:-1:/-6.(?:2(?:0{5}\d+)?|29{5}\d+) +6.35:-1:/6.(?:4|39{5}\d+|29{8}\d+) -6.35:-1:/-6.(?:4|39{5}\d+|29{8}\d+) -0.0065:-1:0.0 -0.0065:-2:/-0\.01|-1e-02 -0.0065:-3:/-0\.006|-7e-03 -0.0065:-4:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 -0.0065:-5:/-0\.006(?:5|49{5}\d+)|-6\.5e-03 0.05:0:0 0.5:0:0 0.51:0:1 0.41:0:0 0.01234567:-3:0.012 0.01234567:-4:0.0123 0.01234567:-5:0.01235 0.01234567:-6:0.012346 0.01234567:-7:0.0123457 0.01234567:-8:0.01234567 0.01234567:-9:0.012345670 0.01234567:-12:0.012345670000 &fcmp fcmpNaN:fcmpNaN: fcmpNaN:+0: +0:fcmpNaN: +0:+0:0 -1:+0:-1 +0:-1:1 +1:+0:1 +0:+1:-1 -1:+1:-1 +1:-1:1 -1:-1:0 +1:+1:0 -1.1:0:-1 +0:-1.1:1 +1.1:+0:1 +0:+1.1:-1 +123:+123:0 +123:+12:1 +12:+123:-1 -123:-123:0 -123:-12:-1 -12:-123:1 +123:+124:-1 +124:+123:1 -123:-124:1 -124:-123:-1 0:0.01:-1 0:0.0001:-1 0:-0.0001:1 0:-0.1:1 0.1:0:1 0.00001:0:1 -0.0001:0:-1 -0.1:0:-1 0:0.0001234:-1 0:-0.0001234:1 0.0001234:0:1 -0.0001234:0:-1 0.0001:0.0005:-1 0.0005:0.0001:1 0.005:0.0001:1 0.001:0.0005:1 0.000001:0.0005:-1 0.00000123:0.0005:-1 0.00512:0.0001:1 0.005:0.000112:1 0.00123:0.0005:1 1.5:2:-1 2:1.5:1 1.54321:234:-1 234:1.54321:1 1e1234567890987654321:1e1234567890987654320:1 1e-1234567890987654321:1e-1234567890987654320:-1 # infinity -inf:5432112345:-1 +inf:5432112345:1 -inf:-5432112345:-1 +inf:-5432112345:1 -inf:54321.12345:-1 +inf:54321.12345:1 -inf:-54321.12345:-1 +inf:-54321.12345:1 +inf:+inf:0 -inf:-inf:0 +inf:-inf:1 -inf:+inf:-1 # return undef +inf:NaN: NaN:inf: -inf:NaN: NaN:-inf: &facmp fcmpNaN:fcmpNaN: fcmpNaN:+0: +0:fcmpNaN: +0:+0:0 -1:+0:1 +0:-1:-1 +1:+0:1 +0:+1:-1 -1:+1:0 +1:-1:0 -1:-1:0 +1:+1:0 -1.1:0:1 +0:-1.1:-1 +1.1:+0:1 +0:+1.1:-1 +123:+123:0 +123:+12:1 +12:+123:-1 -123:-123:0 -123:-12:1 -12:-123:-1 +123:+124:-1 +124:+123:1 -123:-124:-1 -124:-123:1 0:0.01:-1 0:0.0001:-1 0:-0.0001:-1 0:-0.1:-1 0.1:0:1 0.00001:0:1 -0.0001:0:1 -0.1:0:1 0:0.0001234:-1 0:-0.0001234:-1 0.0001234:0:1 -0.0001234:0:1 0.0001:0.0005:-1 0.0005:0.0001:1 0.005:0.0001:1 0.001:0.0005:1 0.000001:0.0005:-1 0.00000123:0.0005:-1 0.00512:0.0001:1 0.005:0.000112:1 0.00123:0.0005:1 1.5:2:-1 2:1.5:1 1.54321:234:-1 234:1.54321:1 # infinity -inf:5432112345:1 +inf:5432112345:1 -inf:-5432112345:1 +inf:-5432112345:1 -inf:54321.12345:1 +inf:54321.12345:1 -inf:-54321.12345:1 +inf:-54321.12345:1 +inf:+inf:0 -inf:-inf:0 +inf:-inf:0 -inf:+inf:0 5:inf:-1 -1:inf:-1 5:-inf:-1 -1:-inf:-1 # return undef +inf:facmpNaN: facmpNaN:inf: -inf:facmpNaN: facmpNaN:-inf: &fdec fdecNaN:NaN +inf:inf -inf:-inf +0:-1 +1:0 -1:-2 1.23:0.23 -1.23:-2.23 100:99 101:100 -100:-101 -99:-100 -98:-99 99:98 &finc fincNaN:NaN +inf:inf -inf:-inf +0:1 +1:2 -1:0 1.23:2.23 -1.23:-0.23 100:101 -100:-99 -99:-98 -101:-100 99:100 &fadd abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:-inf:NaN -inf:+inf:NaN +inf:+inf:inf -inf:-inf:-inf baddNaN:+inf:NaN baddNaN:+inf:NaN +inf:baddNaN:NaN -inf:baddNaN:NaN +0:+0:0 +1:+0:1 +0:+1:1 +1:+1:2 -1:+0:-1 +0:-1:-1 -1:-1:-2 -1:+1:0 +1:-1:0 +9:+1:10 +99:+1:100 +999:+1:1000 +9999:+1:10000 +99999:+1:100000 +999999:+1:1000000 +9999999:+1:10000000 +99999999:+1:100000000 +999999999:+1:1000000000 +9999999999:+1:10000000000 +99999999999:+1:100000000000 +10:-1:9 +100:-1:99 +1000:-1:999 +10000:-1:9999 +100000:-1:99999 +1000000:-1:999999 +10000000:-1:9999999 +100000000:-1:99999999 +1000000000:-1:999999999 +10000000000:-1:9999999999 +123456789:+987654321:1111111110 -123456789:+987654321:864197532 -123456789:-987654321:-1111111110 +123456789:-987654321:-864197532 0.001234:0.0001234:0.0013574 &fsub abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:-inf:inf -inf:+inf:-inf +inf:+inf:NaN -inf:-inf:NaN baddNaN:+inf:NaN baddNaN:+inf:NaN +inf:baddNaN:NaN -inf:baddNaN:NaN +0:+0:0 +1:+0:1 +0:+1:-1 +1:+1:0 -1:+0:-1 +0:-1:1 -1:-1:0 -1:+1:-2 +1:-1:2 +9:+1:8 +99:+1:98 +999:+1:998 +9999:+1:9998 +99999:+1:99998 +999999:+1:999998 +9999999:+1:9999998 +99999999:+1:99999998 +999999999:+1:999999998 +9999999999:+1:9999999998 +99999999999:+1:99999999998 +10:-1:11 +100:-1:101 +1000:-1:1001 +10000:-1:10001 +100000:-1:100001 +1000000:-1:1000001 +10000000:-1:10000001 +100000000:-1:100000001 +1000000000:-1:1000000001 +10000000000:-1:10000000001 +123456789:+987654321:-864197532 -123456789:+987654321:-1111111110 -123456789:-987654321:864197532 +123456789:-987654321:1111111110 &bmuladd abc:abc:0:NaN abc:+0:0:NaN +0:abc:0:NaN +0:0:abc:NaN NaNmul:+inf:0:NaN NaNmul:-inf:0:NaN -inf:NaNmul:0:NaN +inf:NaNmul:0:NaN +inf:+inf:0:inf +inf:-inf:0:-inf -inf:+inf:0:-inf -inf:-inf:0:inf +0:+0:0:0 +0:+1:0:0 +1:+0:0:0 +0:-1:0:0 -1:+0:0:0 123456789123456789:0:0:0 0:123456789123456789:0:0 -1:-1:0:1 -1:-1:0:1 -1:+1:0:-1 +1:-1:0:-1 +1:+1:0:1 +2:+3:0:6 -2:+3:0:-6 +2:-3:0:-6 -2:-3:0:6 111:111:0:12321 10101:10101:0:102030201 1001001:1001001:0:1002003002001 100010001:100010001:0:10002000300020001 10000100001:10000100001:0:100002000030000200001 11111111111:9:0:99999999999 22222222222:9:0:199999999998 33333333333:9:0:299999999997 44444444444:9:0:399999999996 55555555555:9:0:499999999995 66666666666:9:0:599999999994 77777777777:9:0:699999999993 88888888888:9:0:799999999992 99999999999:9:0:899999999991 11111111111:9:1:100000000000 22222222222:9:1:199999999999 33333333333:9:1:299999999998 44444444444:9:1:399999999997 55555555555:9:1:499999999996 66666666666:9:1:599999999995 77777777777:9:1:699999999994 88888888888:9:1:799999999993 99999999999:9:1:899999999992 -3:-4:-5:7 3:-4:-5:-17 -3:4:-5:-17 3:4:-5:7 -3:4:5:-7 3:-4:5:-7 9999999999999999999:10000000000000000000:1234567890:99999999999999999990000000001234567890 3.2:5.7:8.9:27.14 -3.2:5.197:6.05:-10.5804 &bmodpow 3:4:8:1 3:4:7:4 3:4:7:4 77777:777:123456789:99995084 3.2:6.2:5.2:2.970579856718063040273642739529400818 &fmul abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:NaNmul:NaN +inf:NaNmul:NaN NaNmul:+inf:NaN NaNmul:-inf:NaN +inf:+inf:inf +inf:-inf:-inf +inf:-inf:-inf +inf:+inf:inf +inf:123.34:inf +inf:-123.34:-inf -inf:123.34:-inf -inf:-123.34:inf 123.34:+inf:inf -123.34:+inf:-inf 123.34:-inf:-inf -123.34:-inf:inf +0:+0:0 +0:+1:0 +1:+0:0 +0:-1:0 -1:+0:0 +123456789123456789:+0:0 +0:+123456789123456789:0 -1:-1:1 -1:+1:-1 +1:-1:-1 +1:+1:1 +2:+3:6 -2:+3:-6 +2:-3:-6 -2:-3:6 +111:+111:12321 +10101:+10101:102030201 +1001001:+1001001:1002003002001 +100010001:+100010001:10002000300020001 +10000100001:+10000100001:100002000030000200001 +11111111111:+9:99999999999 +22222222222:+9:199999999998 +33333333333:+9:299999999997 +44444444444:+9:399999999996 +55555555555:+9:499999999995 +66666666666:+9:599999999994 +77777777777:+9:699999999993 +88888888888:+9:799999999992 +99999999999:+9:899999999991 6:120:720 10:10000:100000 &fdiv-list 0:0:NaN,NaN 0:1:0,0 9:4:2.25,1 9:5:1.8,4 # bug in v1.74 with bdiv in list context, when $y is 1 or -1 2.1:-1:-2.1,0 2.1:1:2.1,0 -2.1:-1:2.1,0 -2.1:1:-2.1,0 &fdiv $div_scale = 40; $round_mode = 'even' abc:abc:NaN abc:+1:abc:NaN +1:abc:NaN -1:abc:NaN 0:abc:NaN +0:+0:NaN +0:+1:0 +1:+0:inf +3214:+0:inf +0:-1:0 -1:+0:-inf -3214:+0:-inf +1:+1:1 -1:-1:1 +1:-1:-1 -1:+1:-1 +1:+2:0.5 +2:+1:2 123:+inf:0 123:-inf:0 +10:+5:2 +100:+4:25 +1000:+8:125 +10000:+16:625 +10000:-16:-625 +999999999999:+9:111111111111 +999999999999:+99:10101010101 +999999999999:+999:1001001001 +999999999999:+9999:100010001 +999999999999999:+99999:10000100001 +1000000000:+9:111111111.1111111111111111111111111111111 +2000000000:+9:222222222.2222222222222222222222222222222 +3000000000:+9:333333333.3333333333333333333333333333333 +4000000000:+9:444444444.4444444444444444444444444444444 +5000000000:+9:555555555.5555555555555555555555555555556 +6000000000:+9:666666666.6666666666666666666666666666667 +7000000000:+9:777777777.7777777777777777777777777777778 +8000000000:+9:888888888.8888888888888888888888888888889 +9000000000:+9:1000000000 +35500000:+113:314159.2920353982300884955752212389380531 +71000000:+226:314159.2920353982300884955752212389380531 +106500000:+339:314159.2920353982300884955752212389380531 +1000000000:+3:333333333.3333333333333333333333333333333 2:25.024996000799840031993601279744051189762:0.07992009269196593320152084692285869265447 123456:1:123456 $div_scale = 20 +1000000000:+9:111111111.11111111111 +2000000000:+9:222222222.22222222222 +3000000000:+9:333333333.33333333333 +4000000000:+9:444444444.44444444444 +5000000000:+9:555555555.55555555556 +6000000000:+9:666666666.66666666667 +7000000000:+9:777777777.77777777778 +8000000000:+9:888888888.88888888889 +9000000000:+9:1000000000 1:10:0.1 1:100:0.01 1:1000:0.001 1:10000:0.0001 1:504:0.001984126984126984127 2:1.987654321:1.0062111801179738436 123456789.123456789123456789123456789:1:123456789.12345678912 # the next two cases are the "old" behaviour, but are now (>v0.01) different #+35500000:+113:314159.292035398230088 #+71000000:+226:314159.292035398230088 +35500000:+113:314159.29203539823009 +71000000:+226:314159.29203539823009 +106500000:+339:314159.29203539823009 +1000000000:+3:333333333.33333333333 $div_scale = 1 # round to accuracy 1 after bdiv +124:+3:40 123456789.1234:1:100000000 # reset scale for further tests $div_scale = 40 &fmod +9:4:1 +9:5:4 +9000:56:40 +56:9000:56 # inf handling, see table in doc 0:inf:0 0:-inf:0 5:inf:5 5:-inf:5 -5:inf:-5 -5:-inf:-5 inf:5:0 -inf:5:0 inf:-5:0 -inf:-5:0 5:5:0 -5:-5:0 inf:inf:NaN -inf:-inf:NaN -inf:inf:NaN inf:-inf:NaN 8:0:8 inf:0:inf # exceptions to remainder rule -inf:0:-inf -8:0:-8 0:0:NaN abc:abc:NaN abc:1:abc:NaN 1:abc:NaN 0:0:NaN 0:1:0 1:0:1 0:-1:0 -1:0:-1 1:1:0 -1:-1:0 1:-1:0 -1:1:0 1:2:1 2:1:0 1000000000:9:1 2000000000:9:2 3000000000:9:3 4000000000:9:4 5000000000:9:5 6000000000:9:6 7000000000:9:7 8000000000:9:8 9000000000:9:0 35500000:113:33 71000000:226:66 106500000:339:99 1000000000:3:1 10:5:0 100:4:0 1000:8:0 10000:16:0 999999999999:9:0 999999999999:99:0 999999999999:999:0 999999999999:9999:0 999999999999999:99999:0 -9:+5:1 +9:-5:-1 -9:-5:-4 -5:3:1 -2:3:1 4:3:1 1:3:1 -5:-3:-2 -2:-3:-2 4:-3:-2 1:-3:-2 4095:4095:0 100041000510123:3:0 152403346:12345:4321 87654321:87654321:0 # now some floating point tests 123:2.5:0.5 1230:2.5:0 123.4:2.5:0.9 123e1:25:5 -2.1:1:0.9 2.1:1:0.1 -2.1:-1:-0.1 2.1:-1:-0.9 -3:1:0 3:1:0 -3:-1:0 3:-1:0 &ffac Nanfac:NaN -1:NaN +inf:inf -inf:NaN 0:1 1:1 2:2 3:6 4:24 5:120 6:720 10:3628800 11:39916800 12:479001600 &froot # sqrt() +0:2:0 +1:2:1 -1:2:NaN # -$x ** (1/2) => -$y, but not in froot() -123.456:2:NaN +inf:2:inf -inf:2:NaN 2:2:1.41421356237309504880168872420969807857 -2:2:NaN 4:2:2 9:2:3 16:2:4 100:2:10 123.456:2:11.11107555549866648462149404118219234119 15241.38393:2:123.4559999756998444766131352122991626468 1.44:2:1.2 12:2:3.464101615137754587054892683011744733886 0.49:2:0.7 0.0049:2:0.07 # invalid ones 1:NaN:NaN -1:NaN:NaN 0:NaN:NaN -inf:NaN:NaN +inf:NaN:NaN NaN:0:NaN NaN:2:NaN NaN:inf:NaN NaN:inf:NaN 12:-inf:NaN 12:inf:NaN +0:0:NaN +1:0:NaN -1:0:NaN -2:0:NaN -123.45:0:NaN +inf:0:NaN 12:1:12 -12:1:NaN 8:-1:NaN -8:-1:NaN # cubic root 8:3:2 -8:3:NaN # fourths root 16:4:2 81:4:3 # see t/bigroot() for more tests &fsqrt +0:0 -1:NaN -2:NaN -16:NaN -123.45:NaN nanfsqrt:NaN +inf:inf -inf:NaN 1:1 2:1.41421356237309504880168872420969807857 4:2 9:3 16:4 100:10 123.456:11.11107555549866648462149404118219234119 15241.38393:123.4559999756998444766131352122991626468 1.44:1.2 # sqrt(1.44) = 1.2, sqrt(e10) = e5 => 12e4 1.44E10:120000 2e10:141421.356237309504880168872420969807857 144e20:120000000000 # proved to be an endless loop under 7-9 12:3.464101615137754587054892683011744733886 0.49:0.7 0.0049:0.07 &is_nan 123:0 abc:1 NaN:1 -123:0 &is_inf +inf::1 -inf::1 abc::0 1::0 NaN::0 -1::0 +inf:-:0 +inf:+:1 -inf:-:1 -inf:+:0 # it must be exactly /^[+-]inf$/ +infinity::0 -infinity::0 &is_odd abc:0 0:0 -1:1 -3:1 1:1 3:1 1000001:1 1000002:0 +inf:0 -inf:0 123.45:0 -123.45:0 2:0 &is_int NaNis_int:0 0:1 1:1 2:1 -2:1 -1:1 -inf:0 +inf:0 123.4567:0 -0.1:0 -0.002:0 &is_even abc:0 0:1 -1:0 -3:0 1:0 3:0 1000001:0 1000002:1 2:1 +inf:0 -inf:0 123.456:0 -123.456:0 0.01:0 -0.01:0 120:1 1200:1 -1200:1 &is_positive 0:0 1:1 -1:0 -123:0 NaN:0 -inf:0 +inf:1 &is_negative 0:0 1:0 -1:1 -123:1 NaN:0 -inf:1 +inf:0 &parts 0:0 1 1:1 0 123:123 0 -123:-123 0 -1200:-12 2 NaNparts:NaN NaN +inf:inf inf -inf:-inf inf &exponent 0:1 1:0 123:0 -123:0 -1200:2 +inf:inf -inf:inf NaNexponent:NaN &mantissa 0:0 1:1 123:123 -123:-123 -1200:-12 +inf:inf -inf:-inf NaNmantissa:NaN &length 123:3 -123:3 0:1 1:1 12345678901234567890:20 &is_zero NaNzero:0 +inf:0 -inf:0 0:1 -1:0 1:0 &is_one NaNone:0 +inf:0 -inf:0 0:0 2:0 1:1 -1:0 -2:0 &ffloor 0:0 abc:NaN +inf:inf -inf:-inf 1:1 -51:-51 -51.2:-52 12.2:12 0.12345:0 0.123456:0 0.1234567:0 0.12345678:0 0.123456789:0 &fceil 0:0 abc:NaN +inf:inf -inf:-inf 1:1 -51:-51 -51.2:-51 12.2:13 Math-BigInt-GMP-1.37/t/bigfltpm.t0000644005434300244210000000151611630076051016323 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; use Test::More tests => 2322 + 5; # own tests use Math::BigInt lib => 'Calc'; use Math::BigFloat; use vars qw ($class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL); $class = "Math::BigFloat"; $CL = "Math::BigInt::Calc"; is ($class->config()->{class},$class); is ($class->config()->{with}, $CL); # bug #17447: Can't call method Math::BigFloat->bsub, not a valid method my $c = Math::BigFloat->new( '123.3' ); is ($c->fsub(123), '0.3'); # calling fsub on a BigFloat works # Bug until BigInt v1.86, the scale wasn't treated as a scalar: $c = Math::BigFloat->new('0.008'); my $d = Math::BigFloat->new(3); my $e = $c->bdiv(Math::BigFloat->new(3),$d); is ($e,'0.00267'); # '0.008 / 3 => 0.0027'); is (ref($e->{_e}->[0]), ''); # 'Not a BigInt'); require 't/bigfltpm.inc'; # all tests here for sharing Math-BigInt-GMP-1.37/t/bigintg.t0000644005434300244210000003152311523605316016146 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; use Test; BEGIN { $| = 1; chdir 't' if -d 't'; unshift @INC, '../lib'; # for running manually unshift @INC, '../blib/arch'; # for running manually plan tests => 356; } use Math::BigInt::GMP; # testing of Math::BigInt::GMP my $C = 'Math::BigInt::GMP'; # pass classname to sub's # _new and _str my $x = $C->_new("123"); my $y = $C->_new("321"); ok (ref($x),'Math::BigInt::GMP'); ok ($C->_str($x),123); ok ($C->_str($y),321); ############################################################################### # _set my $b = $C->_new("123"); $C->_set($b,12); ok ($C->_str($b),12); ############################################################################### # _add, _sub, _mul, _div ok ($C->_str($C->_add($x,$y)),444); ok ($C->_str($C->_sub($x,$y)),123); ok ($C->_str($x),123); ok ($C->_str($y),321); ok ($C->_str($C->_mul($x,$y)),39483); ok ($C->_str(scalar $C->_div($x,$y)),123); ############################################################################### # check that mul/div doesn't change $y # and returns the same reference, not something new ok ($C->_str($C->_mul($x,$y)),39483); ok ($C->_str($x),39483); ok ($C->_str($y),321); ok ($C->_str(scalar $C->_div($x,$y)),123); ok ($C->_str($x),123); ok ($C->_str($y),321); $x = $C->_new("39483"); my ($x1,$r1) = $C->_div($x,$y); ok ("$x1","$x"); $C->_inc($x1); ok ("$x1","$x"); ok ($C->_str($r1),'0'); ############################################################################### # check that sub modifies the right argument: $x = $C->_new("221"); $y = $C->_new("444"); $x = $C->_sub($y,$x,1); # 444 - 221 => 223 ok ($C->_str($x),223); ok ($C->_str($y),444); $x = $C->_new("444"); $y = $C->_new("221"); ok ($C->_str($C->_sub($x,$y)),223); # 444 - 221 => 223 ok ($C->_str($x),223); ok ($C->_str($y),221); ############################################################################### $x = $C->_new("39483"); # reset $y = $C->_new("321"); # reset my $z = $C->_new("2"); ok ($C->_str($C->_add($x,$z)),39485); my ($re,$rr) = $C->_div($x,$y); ok ($C->_str($re),123); ok ($C->_str($rr),2); # is_zero, _is_one, _one, _zero ok ($C->_is_zero($x)||0,0); ok ($C->_is_one($x)||0,0); ok ($C->_str($C->_zero()),"0"); ok ($C->_str($C->_one()),"1"); # _two() and _ten() ok ($C->_str($C->_two()),"2"); ok ($C->_str($C->_ten()),"10"); ok ($C->_is_ten($C->_two()),0); ok ($C->_is_two($C->_two()),1); ok ($C->_is_ten($C->_ten()),1); ok ($C->_is_two($C->_ten()),0); ok ($C->_is_one($C->_one()),1); ok ($C->_is_one($C->_two()),0); ok ($C->_is_one($C->_ten()),0); ok ($C->_is_one($C->_zero()) || 0,0); ok ($C->_is_zero($C->_zero()),1); ok ($C->_is_zero($C->_one()) || 0,0); # is_odd, is_even ok ($C->_is_odd($C->_one()),1); ok ($C->_is_odd($C->_zero())||0,0); ok ($C->_is_even($C->_one()) || 0,0); ok ($C->_is_even($C->_zero()),1); sub _check_len { my ($y, $m) = @_; my $len = length($y); $x = $C->_new($y); if ($m eq '_len') { ok ($C->$m($x),$len); } else { # equal or at most one bigger print STDERR "# $len $y". $C->$m($x). "\n" unless ok ($len - $C->$m($x) <= 1, 1); } } # _len and _alen for my $m (qw/_len _alen/) { _check_len("1",$m); _check_len("12",$m); _check_len("123",$m); _check_len("1234",$m); _check_len("12345",$m); _check_len("123456",$m); _check_len("1234567",$m); _check_len("12345678",$m); _check_len("123456789",$m); _check_len("1234567890",$m); _check_len("7",$m); _check_len("8",$m); _check_len("9",$m); _check_len("10",$m); _check_len("11",$m); _check_len("21",$m); _check_len("321",$m); _check_len("320",$m); _check_len("4321",$m); _check_len("54321",$m); _check_len("654321",$m); _check_len("7654321",$m); _check_len("7654321",$m); _check_len("87654321",$m); _check_len("987654321",$m); _check_len("9876543219876543210",$m); _check_len("1234567890" x 10,$m); _check_len("1234567890" x 100,$m); for (my $i = 1; $i < 9; $i++) { my $a = "$i" . '0' x ($i-1); _check_len($a,$m); } } # _digit $x = $C->_new("123456789"); ok ($C->_digit($x,0),9); ok ($C->_digit($x,1),8); ok ($C->_digit($x,2),7); ok ($C->_digit($x,-1),1); ok ($C->_digit($x,-2),2); ok ($C->_digit($x,-3),3); # _copy foreach (qw/ 1 12 123 1234 12345 123456 1234567 12345678 123456789/) { $x = $C->_new("$_"); ok ($C->_str($C->_copy($x)),"$_"); ok ($C->_str($x),"$_"); # did _copy destroy original x? } # _zeros $x = $C->_new("1256000000"); ok ($C->_zeros($x),6); $x = $C->_new("152"); ok ($C->_zeros($x),0); $x = $C->_new("123000"); ok ($C->_zeros($x),3); $x = $C->_new("123001"); ok ($C->_zeros($x),0); $x = $C->_new("1"); ok ($C->_zeros($x),0); $x = $C->_new("8"); ok ($C->_zeros($x),0); $x = $C->_new("10"); ok ($C->_zeros($x),1); $x = $C->_new("11"); ok ($C->_zeros($x),0); $x = $C->_new("0"); ok ($C->_zeros($x),0); # _lsft, _rsft $x = $C->_new("10"); $y = $C->_new("3"); ok ($C->_str($C->_lsft($x,$y,10)),10000); $x = $C->_new("20"); $y = $C->_new("3"); ok ($C->_str($C->_lsft($x,$y,10)),20000); $x = $C->_new("128"); $y = $C->_new("4"); ok ($C->_str($C->_lsft($x,$y,2)), 128 << 4); $x = $C->_new("1000"); $y = $C->_new("3"); ok ($C->_str($C->_rsft($x,$y,10)),1); $x = $C->_new("20000"); $y = $C->_new("3"); ok ($C->_str($C->_rsft($x,$y,10)),20); $x = $C->_new("256"); $y = $C->_new("4"); ok ($C->_str($C->_rsft($x,$y,2)),256 >> 4); $x = $C->_new("6411906467305339182857313397200584952398"); $y = $C->_new("45"); ok ($C->_str($C->_rsft($x,$y,10)),0); # _acmp $x = $C->_new("123456789"); $y = $C->_new("987654321"); ok ($C->_acmp($x,$y),-1); ok ($C->_acmp($y,$x),1); ok ($C->_acmp($x,$x),0); ok ($C->_acmp($y,$y),0); $x = $C->_new("12"); $y = $C->_new("12"); ok ($C->_acmp($x,$y),0); $x = $C->_new("21"); ok ($C->_acmp($x,$y),1); ok ($C->_acmp($y,$x),-1); $x = $C->_new("123456789"); $y = $C->_new("1987654321"); ok ($C->_acmp($x,$y),-1); ok ($C->_acmp($y,$x),+1); $x = $C->_new("1234567890123456789"); $y = $C->_new("987654321012345678"); ok ($C->_acmp($x,$y),1); ok ($C->_acmp($y,$x),-1); ok ($C->_acmp($x,$x),0); ok ($C->_acmp($y,$y),0); $x = $C->_new("1234"); $y = $C->_new("987654321012345678"); ok ($C->_acmp($x,$y),-1); ok ($C->_acmp($y,$x),1); ok ($C->_acmp($x,$x),0); ok ($C->_acmp($y,$y),0); # _modinv $x = $C->_new("8"); $y = $C->_new("5033"); my ($xmod,$sign) = $C->_modinv($x,$y); ok ($C->_str($xmod),'4404'); # (4404 * 8) % 5033 = 1 ok ($sign, '+'); # _div $x = $C->_new("3333"); $y = $C->_new("1111"); ok ($C->_str(scalar $C->_div($x,$y)),3); $x = $C->_new("33333"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y); ok ($C->_str($x),30); ok ($C->_str($y),3); $x = $C->_new("123"); $y = $C->_new("1111"); ($x,$y) = $C->_div($x,$y); ok ($C->_str($x),0); ok ($C->_str($y),123); # _num foreach (qw/1 12 123 1234 12345 1234567 12345678 123456789 1234567890/) { $x = $C->_new("$_"); ok (ref($x)||'','Math::BigInt::GMP'); ok ($C->_str($x),"$_"); $x = $C->_num($x); ok (ref($x)||'',''); ok ($x,$_); } # _sqrt $x = $C->_new("144"); ok ($C->_str($C->_sqrt($x)),'12'); $x = $C->_new("144000000000000"); ok ($C->_str($C->_sqrt($x)),'12000000'); # _root $x = $C->_new("81"); my $n = $C->_new("3"); # 4*4*4 = 64, 5*5*5 = 125 ok ($C->_str($C->_root($x,$n)),'4'); # 4.xx => 4.0 $x = $C->_new("81"); $n = $C->_new("4"); # 3*3*3*3 == 81 ok ($C->_str($C->_root($x,$n)),'3'); # _pow (and _root) $x = $C->_new("0"); $n = $C->_new("3"); # 0 ** y => 0 ok ($C->_str($C->_pow($x,$n)), 0); $x = $C->_new("3"); $n = $C->_new("0"); # x ** 0 => 1 ok ($C->_str($C->_pow($x,$n)), 1); $x = $C->_new("1"); $n = $C->_new("3"); # 1 ** y => 1 ok ($C->_str($C->_pow($x,$n)), 1); $x = $C->_new("5"); $n = $C->_new("1"); # x ** 1 => x ok ($C->_str($C->_pow($x,$n)), 5); $x = $C->_new("81"); $n = $C->_new("3"); # 81 ** 3 == 531441 ok ($C->_str($C->_pow($x,$n)),81 ** 3); ok ($C->_str($C->_root($x,$n)),81); $x = $C->_new("81"); ok ($C->_str($C->_pow($x,$n)),81 ** 3); ok ($C->_str($C->_pow($x,$n)),'150094635296999121'); # 531441 ** 3 == ok ($C->_str($C->_root($x,$n)),'531441'); ok ($C->_str($C->_root($x,$n)),'81'); $x = $C->_new("81"); $n = $C->_new("14"); ok ($C->_str($C->_pow($x,$n)),'523347633027360537213511521'); ok ($C->_str($C->_root($x,$n)),'81'); $x = $C->_new("523347633027360537213511520"); ok ($C->_str($C->_root($x,$n)),'80'); $x = $C->_new("523347633027360537213511522"); ok ($C->_str($C->_root($x,$n)),'81'); my $res = [ qw/ 9 31 99 316 999 3162 9999/ ]; # 99 ** 2 = 9801, 999 ** 2 = 998001 etc for my $i (2 .. 9) { $x = '9' x $i; $x = $C->_new($x); $n = $C->_new("2"); my $rc = '9' x ($i-1). '8' . '0' x ($i-1) . '1'; print "# _pow( ", '9' x $i, ", 2) \n" unless ok ($C->_str($C->_pow($x,$n)),$rc); if ($i <= 7) { $x = '9' x $i; $x = $C->_new($x); $n = '9' x $i; $n = $C->_new($n); print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless ok ($C->_str($C->_root($x,$n)),'1'); $x = '9' x $i; $x = $C->_new($x); $n = $C->_new("2"); print "# _root( ", '9' x $i, ", ", 9 x $i, ") \n" unless ok ($C->_str($C->_root($x,$n)), $res->[$i-2]); } } ############################################################################## # _fac $x = $C->_new("0"); ok ($C->_str($C->_fac($x)),'1'); $x = $C->_new("1"); ok ($C->_str($C->_fac($x)),'1'); $x = $C->_new("2"); ok ($C->_str($C->_fac($x)),'2'); $x = $C->_new("3"); ok ($C->_str($C->_fac($x)),'6'); $x = $C->_new("4"); ok ($C->_str($C->_fac($x)),'24'); $x = $C->_new("5"); ok ($C->_str($C->_fac($x)),'120'); $x = $C->_new("10"); ok ($C->_str($C->_fac($x)),'3628800'); $x = $C->_new("11"); ok ($C->_str($C->_fac($x)),'39916800'); $x = $C->_new("12"); ok ($C->_str($C->_fac($x)),'479001600'); $x = $C->_new("13"); ok ($C->_str($C->_fac($x)),'6227020800'); # test that _fac modifes $x in place for small arguments $x = $C->_new("3"); $C->_fac($x); ok ($C->_str($x),'6'); $x = $C->_new("13"); $C->_fac($x); ok ($C->_str($x),'6227020800'); ############################################################################## # _inc and _dec foreach (qw/1 11 121 1231 12341 1234561 12345671 123456781 1234567891/) { $x = $C->_new("$_"); $C->_inc($x); print "# \$x = ",$C->_str($x),"\n" unless ok ($C->_str($x),substr($_,0,length($_)-1) . '2'); $C->_dec($x); ok ($C->_str($x),$_); } foreach (qw/19 119 1219 12319 1234519 12345619 123456719 1234567819/) { $x = $C->_new("$_"); $C->_inc($x); print "# \$x = ",$C->_str($x),"\n" unless ok ($C->_str($x),substr($_,0,length($_)-2) . '20'); $C->_dec($x); ok ($C->_str($x),$_); } foreach (qw/999 9999 99999 9999999 99999999 999999999 9999999999 99999999999/) { $x = $C->_new("$_"); $C->_inc($x); print "# \$x = ",$C->_str($x),"\n" unless ok ($C->_str($x), '1' . '0' x (length($_))); $C->_dec($x); ok ($C->_str($x),$_); } $x = $C->_new("1000"); $C->_inc($x); ok ($C->_str($x),'1001'); $C->_dec($x); ok ($C->_str($x),'1000'); ############################################################################### # _log_int (test handling of plain scalar as base, bug up to v1.17) $x = $C->_new("81"); my ($r, $exact) = $C->_log_int($x, $C->_new("3")); ok ($C->_str( $r ), '4'); ok ($C->_str( $x ), '4'); ok ($exact, 1); $x = $C->_new("81"); ($r, $exact) = $C->_log_int($x,3); ok ($C->_str( $r ), '4'); ok ($C->_str( $x ), '4'); ok ($exact, 1); ############################################################################### # _mod $x = $C->_new("1000"); $y = $C->_new("3"); ok ($C->_str(scalar $C->_mod($x,$y)),1); $x = $C->_new("1000"); $y = $C->_new("2"); ok ($C->_str(scalar $C->_mod($x,$y)),0); # _and, _or, _xor $x = $C->_new("5"); $y = $C->_new("2"); ok ($C->_str(scalar $C->_xor($x,$y)),7); $x = $C->_new("5"); $y = $C->_new("2"); ok ($C->_str(scalar $C->_or($x,$y)),7); $x = $C->_new("5"); $y = $C->_new("3"); ok ($C->_str(scalar $C->_and($x,$y)),1); # _from_hex, _from_bin ok ($C->_str( $C->_from_hex("0xFf")),255); ok ($C->_str( $C->_from_bin("0b10101011")),160+11); # _as_hex, _as_bin ok ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new("128")))), 128); ok ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new("128")))), 128); ok ($C->_str( $C->_from_hex( $C->_as_hex( $C->_new("0")))), 0); ok ($C->_str( $C->_from_bin( $C->_as_bin( $C->_new("0")))), 0); ok ($C->_as_hex( $C->_new("0")), '0x0'); ok ($C->_as_bin( $C->_new("0")), '0b0'); ok ($C->_as_hex( $C->_new("12")), '0xc'); ok ($C->_as_bin( $C->_new("12")), '0b1100'); # _from_oct $x = $C->_from_oct("001"); ok ($C->_str($x),'1'); $x = $C->_from_oct("07"); ok ($C->_str($x),'7'); $x = $C->_from_oct("077"); ok ($C->_str($x),'63'); $x = $C->_from_oct("07654321"); ok ($C->_str($x),'2054353'); # _as_oct $x = $C->_new("2054353"); ok ($C->_as_oct($x),'07654321'); $x = $C->_new("63"); ok ($C->_as_oct($x),'077'); $x = $C->_new("0"); ok ($C->_as_oct($x),'00'); # _1ex ok ($C->_str($C->_1ex(0)), "1"); ok ($C->_str($C->_1ex(1)), "10"); ok ($C->_str($C->_1ex(2)), "100"); ok ($C->_str($C->_1ex(12)), "1000000000000"); ok ($C->_str($C->_1ex(16)), "10000000000000000"); # _check $x = $C->_new("123456789"); ok ($C->_check($x),0); ok ($C->_check(123),'123 is not a reference to Math::BigInt::GMP'); # done 1; Math-BigInt-GMP-1.37/t/bigintpm.inc0000644005434300244210000015761211630076171016652 0ustar OSPJADomain Users#include this file into another for subclass testing my $version = ${"$class\::VERSION"}; use strict; ############################################################################## # for testing inheritance of _swap package Math::Foo; use Math::BigInt lib => $main::CL; use vars qw/@ISA/; @ISA = (qw/Math::BigInt/); use overload # customized overload for sub, since original does not use swap there '-' => sub { my @a = ref($_[0])->_swap(@_); $a[0]->bsub($a[1])}; sub _swap { # a fake _swap, which reverses the params my $self = shift; # for override in subclass if ($_[2]) { my $c = ref ($_[0] ) || 'Math::Foo'; return ( $_[0]->copy(), $_[1] ); } else { return ( Math::Foo->new($_[1]), $_[0] ); } } ############################################################################## package main; my $CALC = $class->config()->{lib}; is ($CALC,$CL); my ($f,$z,$a,$exp,@a,$m,$e,$round_mode,$expected_class); while () { $_ =~ s/[\n\r]//g; # remove newlines next if /^#/; # skip comments if (s/^&//) { $f = $_; next; } elsif (/^\$/) { $round_mode = $_; $round_mode =~ s/^\$/$class\->/; next; } @args = split(/:/,$_,99); $ans = pop(@args); $expected_class = $class; if ($ans =~ /(.*?)=(.*)/) { $expected_class = $2; $ans = $1; } $try = "\$x = $class->new(\"$args[0]\");"; if ($f eq "bnorm") { $try = "\$x = $class->bnorm(\"$args[0]\");"; # some is_xxx tests } elsif ($f =~ /^is_(zero|one|odd|even|negative|positive|nan|int)$/) { $try .= "\$x->$f() || 0;"; } elsif ($f eq "is_inf") { $try .= "\$x->is_inf('$args[1]');"; } elsif ($f eq "binf") { $try .= "\$x->binf('$args[1]');"; } elsif ($f eq "bone") { $try .= "\$x->bone('$args[1]');"; # some unary ops } elsif ($f =~ /^b(nan|floor|ceil|sstr|neg|abs|sgn|inc|dec|not|sqrt|fac)$/) { $try .= "\$x->$f();"; } elsif ($f =~ /^(numify|length|stringify|as_hex|as_bin)$/) { $try .= "\$x->$f();"; } elsif ($f eq "exponent"){ # ->bstr() to see if an object is returned $try .= '$x = $x->exponent()->bstr();'; } elsif ($f eq "mantissa"){ # ->bstr() to see if an object is returned $try .= '$x = $x->mantissa()->bstr();'; } elsif ($f eq "parts"){ $try .= '($m,$e) = $x->parts();'; # ->bstr() to see if an object is returned $try .= '$m = $m->bstr(); $m = "NaN" if !defined $m;'; $try .= '$e = $e->bstr(); $e = "NaN" if !defined $e;'; $try .= '"$m,$e";'; }elsif ($f eq "bexp"){ $try .= "\$x->bexp();"; } elsif ($f eq "bpi"){ $try .= "$class\->bpi(\$x);"; } else { # binary ops $try .= "\$y = $class->new('$args[1]');"; if ($f eq "bcmp") { $try .= '$x->bcmp($y);'; } elsif ($f eq "bround") { $try .= "$round_mode; \$x->bround(\$y);"; } elsif ($f eq "bacmp"){ $try .= '$x->bacmp($y);'; } elsif ($f eq "badd"){ $try .= '$x + $y;'; } elsif ($f eq "bsub"){ $try .= '$x - $y;'; } elsif ($f eq "bmul"){ $try .= '$x * $y;'; } elsif ($f eq "bdiv"){ $try .= '$x / $y;'; } elsif ($f eq "bdiv-list"){ $try .= 'join (",",$x->bdiv($y));'; # overload via x= } elsif ($f =~ /^.=$/){ $try .= "\$x $f \$y;"; # overload via x } elsif ($f =~ /^.$/){ $try .= "\$x $f \$y;"; } elsif ($f eq "bmod"){ $try .= '$x % $y;'; } elsif ($f eq "bgcd") { if (defined $args[2]) { $try .= " \$z = $class->new('$args[2]'); "; } $try .= "$class\::bgcd(\$x, \$y"; $try .= ", \$z" if (defined $args[2]); $try .= " );"; } elsif ($f eq "blcm") { if (defined $args[2]) { $try .= " \$z = $class->new('$args[2]'); "; } $try .= "$class\::blcm(\$x, \$y"; $try .= ", \$z" if (defined $args[2]); $try .= " );"; }elsif ($f eq "blsft"){ if (defined $args[2]) { $try .= "\$x->blsft(\$y,$args[2]);"; } else { $try .= "\$x << \$y;"; } }elsif ($f eq "brsft"){ if (defined $args[2]) { $try .= "\$x->brsft(\$y,$args[2]);"; } else { $try .= "\$x >> \$y;"; } }elsif ($f eq "bnok"){ $try .= "\$x->bnok(\$y);"; }elsif ($f eq "broot"){ $try .= "\$x->broot(\$y);"; }elsif ($f eq "blog"){ $try .= "\$x->blog(\$y);"; }elsif ($f eq "band"){ $try .= "\$x & \$y;"; }elsif ($f eq "bior"){ $try .= "\$x | \$y;"; }elsif ($f eq "bxor"){ $try .= "\$x ^ \$y;"; }elsif ($f eq "bpow"){ $try .= "\$x ** \$y;"; } elsif( $f eq "bmodinv") { $try .= "\$x->bmodinv(\$y);"; }elsif ($f eq "digit"){ $try .= "\$x->digit(\$y);"; }elsif ($f eq "batan2"){ $try .= "\$x->batan2(\$y);"; } else { # Functions with three arguments $try .= "\$z = $class->new(\"$args[2]\");"; if( $f eq "bmodpow") { $try .= "\$x->bmodpow(\$y,\$z);"; } elsif ($f eq "bmuladd"){ $try .= "\$x->bmuladd(\$y,\$z);"; } else { warn "Unknown op '$f'"; } } } # end else all other ops $ans1 = eval $try; # convert hex/binary targets to decimal if ($ans =~ /^(0x0x|0b0b)/) { $ans =~ s/^0[xb]//; $ans = Math::BigInt->new($ans)->bstr(); } if ($ans eq "") { is ($ans1, undef); } else { # print "try: $try ans: $ans1 $ans\n"; print "# Tried: '$try'\n" if !is ($ans1, $ans); is (ref($ans),$expected_class) if $expected_class ne $class; } # check internal state of number objects is_valid($ans1,$f) if ref $ans1; } # endwhile data tests close DATA; # test some more @a = (); for (my $i = 1; $i < 10; $i++) { push @a, $i; } is("@a", "1 2 3 4 5 6 7 8 9"); # test whether self-multiplication works correctly (result is 2**64) $try = "\$x = $class->new('4294967296');"; $try .= '$a = $x->bmul($x);'; $ans1 = eval $try; print "# Tried: '$try'\n" if !is ($ans1, $class->new(2) ** 64); # test self-pow $try = "\$x = $class->new(10);"; $try .= '$a = $x->bpow($x);'; $ans1 = eval $try; print "# Tried: '$try'\n" if !is ($ans1, $class->new(10) ** 10); ############################################################################### # test whether op destroys args or not (should better not) $x = $class->new(3); $y = $class->new(4); $z = $x & $y; is ($x,3); is ($y,4); is ($z,0); $z = $x | $y; is ($x,3); is ($y,4); is ($z,7); $x = $class->new(1); $y = $class->new(2); $z = $x | $y; is ($x,1); is ($y,2); is ($z,3); $x = $class->new(5); $y = $class->new(4); $z = $x ^ $y; is ($x,5); is ($y,4); is ($z,1); $x = $class->new(-5); $y = -$x; is ($x, -5); $x = $class->new(-5); $y = abs($x); is ($x, -5); $x = $class->new(8); $y = $class->new(-1); $z = $class->new(5033); my $u = $x->copy()->bmodpow($y,$z); is ($u,4404); is ($y,-1); is ($z,5033); $x = $class->new(-5); $y = -$x; is ($x,-5); is ($y,5); $x = $class->new(-5); $y = $x->copy()->bneg(); is ($x,-5); is ($y,5); $x = $class->new(-5); $y = $class->new(3); $x->bmul($y); is ($x,-15); is ($y,3); $x = $class->new(-5); $y = $class->new(3); $x->badd($y); is ($x,-2); is ($y,3); $x = $class->new(-5); $y = $class->new(3); $x->bsub($y); is ($x,-8); is ($y,3); $x = $class->new(-15); $y = $class->new(3); $x->bdiv($y); is ($x,-5); is ($y,3); $x = $class->new(-5); $y = $class->new(3); $x->bmod($y); is ($x,1); is ($y,3); $x = $class->new(5); $y = $class->new(3); $x->bmul($y); is ($x,15); is ($y,3); $x = $class->new(5); $y = $class->new(3); $x->badd($y); is ($x,8); is ($y,3); $x = $class->new(5); $y = $class->new(3); $x->bsub($y); is ($x,2); is ($y,3); $x = $class->new(15); $y = $class->new(3); $x->bdiv($y); is ($x,5); is ($y,3); $x = $class->new(5); $y = $class->new(3); $x->bmod($y); is ($x,2); is ($y,3); $x = $class->new(5); $y = $class->new(-3); $x->bmul($y); is ($x,-15); is ($y,-3); $x = $class->new(5); $y = $class->new(-3); $x->badd($y); is ($x,2); is ($y,-3); $x = $class->new(5); $y = $class->new(-3); $x->bsub($y); is ($x,8); is ($y,-3); $x = $class->new(15); $y = $class->new(-3); $x->bdiv($y); is ($x,-5); is ($y,-3); $x = $class->new(5); $y = $class->new(-3); $x->bmod($y); is ($x,-1); is ($y,-3); ############################################################################### # check whether overloading cmp works $try = "\$x = $class->new(0);"; $try .= "\$y = 10;"; $try .= "'false' if \$x ne \$y;"; $ans = eval $try; print "# For '$try'\n" if (!is ("$ans" , "false") ); # we cant test for working cmpt with other objects here, we would need a dummy # object with stringify overload for this. see Math::String tests as example ############################################################################### # check reversed order of arguments $try = "\$x = $class->new(10); \$x = 2 ** \$x;"; $try .= "'ok' if \$x == 1024;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class->new(10); \$x = 2 * \$x;"; $try .= "'ok' if \$x == 20;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class->new(10); \$x = 2 + \$x;"; $try .= "'ok' if \$x == 12;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(10); \$x = 2 - \$x;"; $try .= "'ok' if \$x == -8;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(10); \$x = 20 / \$x;"; $try .= "'ok' if \$x == 2;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(3); \$x = 20 % \$x;"; $try .= "'ok' if \$x == 2;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(7); \$x = 20 & \$x;"; $try .= "'ok' if \$x == 4;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(7); \$x = 0x20 | \$x;"; $try .= "'ok' if \$x == 0x27;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); $try = "\$x = $class\->new(7); \$x = 0x20 ^ \$x;"; $try .= "'ok' if \$x == 0x27;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); ############################################################################### # check badd(4,5) form $try = "\$x = $class\->badd(4,5);"; $try .= "'ok' if \$x == 9;"; $ans = eval $try; print "# For '$try'\n" if (!ok "$ans" , "ok" ); ############################################################################### # check undefs: NOT DONE YET ############################################################################### # bool $x = $class->new(1); if ($x) { is (1,1); } else { is ($x,'to be true') } $x = $class->new(0); if (!$x) { is (1,1); } else { is ($x,'to be false') } ############################################################################### # objectify() @args = Math::BigInt::objectify(2,4,5); is (scalar @args,3); # $class, 4, 5 like ($args[0], qr/^Math::BigInt/); is ($args[1],4); is ($args[2],5); @args = Math::BigInt::objectify(0,4,5); is (scalar @args,3); # $class, 4, 5 like ($args[0], qr/^Math::BigInt/); is ($args[1],4); is ($args[2],5); @args = Math::BigInt::objectify(2,4,5); is (scalar @args,3); # $class, 4, 5 like ($args[0], qr/^Math::BigInt/); is ($args[1],4); is ($args[2],5); @args = Math::BigInt::objectify(2,4,5,6,7); is (scalar @args,5); # $class, 4, 5, 6, 7 like ($args[0], qr/^Math::BigInt/); is ($args[1],4); is (ref($args[1]),$args[0]); is ($args[2],5); is (ref($args[2]),$args[0]); is ($args[3],6); is (ref($args[3]),''); is ($args[4],7); is (ref($args[4]),''); @args = Math::BigInt::objectify(2,$class,4,5,6,7); is (scalar @args,5); # $class, 4, 5, 6, 7 is ($args[0],$class); is ($args[1],4); is (ref($args[1]),$args[0]); is ($args[2],5); is (ref($args[2]),$args[0]); is ($args[3],6); is (ref($args[3]),''); is ($args[4],7); is (ref($args[4]),''); ############################################################################### # test whether an opp calls objectify properly or not (or at least does what # it should do given non-objects, w/ or w/o objectify()) is ($class->new(123)->badd(123),246); is ($class->badd(123,321),444); is ($class->badd(123,$class->new(321)),444); is ($class->new(123)->bsub(122),1); is ($class->bsub(321,123),198); is ($class->bsub(321,$class->new(123)),198); is ($class->new(123)->bmul(123),15129); is ($class->bmul(123,123),15129); is ($class->bmul(123,$class->new(123)),15129); is ($class->new(15129)->bdiv(123),123); is ($class->bdiv(15129,123),123); is ($class->bdiv(15129,$class->new(123)),123); is ($class->new(15131)->bmod(123),2); is ($class->bmod(15131,123),2); is ($class->bmod(15131,$class->new(123)),2); is ($class->new(2)->bpow(16),65536); is ($class->bpow(2,16),65536); is ($class->bpow(2,$class->new(16)),65536); is ($class->new(2**15)->brsft(1),2**14); is ($class->brsft(2**15,1),2**14); is ($class->brsft(2**15,$class->new(1)),2**14); is ($class->new(2**13)->blsft(1),2**14); is ($class->blsft(2**13,1),2**14); is ($class->blsft(2**13,$class->new(1)),2**14); ############################################################################### # test for floating-point input (other tests in bnorm() below) $z = 1050000000000000; # may be int on systems with 64bit? $x = $class->new($z); is ($x->bsstr(),'105e+13'); # not 1.05e+15 $z = 1e+129; # definitely a float (may fail on UTS) # don't compare to $z, since some Perl versions stringify $z into something # like '1.e+129' or something equally ugly $x = $class->new($z); is ($x->bsstr(),'1e+129'); ############################################################################### # test for whitespace including newlines to be handled correctly # is ($Math::BigInt::strict,1); # the default foreach my $c ( qw/1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890/) { my $m = $class->new($c); is ($class->new("$c"),$m); is ($class->new(" $c"),$m); is ($class->new("$c "),$m); is ($class->new(" $c "),$m); is ($class->new("\n$c"),$m); is ($class->new("$c\n"),$m); is ($class->new("\n$c\n"),$m); is ($class->new(" \n$c\n"),$m); is ($class->new(" \n$c \n"),$m); is ($class->new(" \n$c\n "),$m); is ($class->new(" \n$c\n1"),'NaN'); is ($class->new("1 \n$c\n1"),'NaN'); } ############################################################################### # prime number tests, also test for **= and length() # found on: http://www.utm.edu/research/primes/notes/by_year.html # ((2^148)-1)/17 $x = $class->new(2); $x **= 148; $x++; $x = $x / 17; is ($x,"20988936657440586486151264256610222593863921"); is ($x->length(),length "20988936657440586486151264256610222593863921"); # MM7 = 2^127-1 $x = $class->new(2); $x **= 127; $x--; is ($x,"170141183460469231731687303715884105727"); $x = $class->new('215960156869840440586892398248'); ($x,$y) = $x->length(); is ($x,30); is ($y,0); $x = $class->new('1_000_000_000_000'); ($x,$y) = $x->length(); is ($x,13); is ($y,0); # test <<=, >>= $x = $class->new('2'); my $y = $class->new('18'); is ($x <<= $y, 2 << 18); is ($x, 2 << 18); is ($x >>= $y, 2); is ($x, 2); # I am afraid the following is not yet possible due to slowness # Also, testing for 2 meg output is a bit hard ;) #$x = $class->new(2); $x **= 6972593; $x--; # 593573509*2^332162+1 has exactly 1,000,000 digits # takes about 24 mins on 300 Mhz, so cannot be done yet ;) #$x = $class->new(2); $x **= 332162; $x *= "593573509"; $x++; #is ($x->length(),1_000_000); ############################################################################### # inheritance and overriding of _swap $x = Math::Foo->new(5); $x = $x - 8; # 8 - 5 instead of 5-8 is ($x,3); is (ref($x),'Math::Foo'); $x = Math::Foo->new(5); $x = 8 - $x; # 5 - 8 instead of 8 - 5 is ($x,-3); is (ref($x),'Math::Foo'); ############################################################################### # Test whether +inf eq inf # This tried to test whether BigInt inf equals Perl inf. Unfortunately, Perl # hasn't (before 5.7.3 at least) a consistent way to say inf, and some things # like 1e100000 crash on some platforms. So simple test for the string 'inf' $x = $class->new('+inf'); is ($x,'inf'); ############################################################################### # numify() and 64 bit integer support require Config; SKIP: { skip("no 64 bit integer support", 4) unless $Config::Config{use64bitint} || $Config::Config{use64bitall}; # The following should not give "1.84467440737096e+19". $x = $class -> new(2) -> bpow(64) -> bdec(); is($x -> bstr(), "18446744073709551615", "bigint 2**64-1 as string"); is($x -> numify(), "18446744073709551615", "bigint 2**64-1 as number"); # The following should not give "-9.22337203685478e+18". $x = $class -> new(2) -> bpow(63) -> bneg(); is($x -> bstr(), "-9223372036854775808", "bigint -2**63 as string"); is($x -> numify(), "-9223372036854775808", "bigint -2**63 as number"); }; ############################################################################### ############################################################################### # the following tests only make sense with Math::BigInt::Calc or BareCalc or # FastCalc exit if $CALC !~ /^Math::BigInt::(|Bare|Fast)Calc$/; # for Pari et al. ############################################################################### # check proper length of internal arrays my $bl = $CL->_base_len(); my $BASE = '9' x $bl; my $MAX = $BASE; $BASE++; $x = $class->new($MAX); is_valid($x); # f.i. 9999 $x += 1; is ($x,$BASE); is_valid($x); # 10000 $x -= 1; is ($x,$MAX); is_valid($x); # 9999 again ############################################################################### # check numify $x = $class->new($BASE-1); is ($x->numify(),$BASE-1); $x = $class->new(-($BASE-1)); is ($x->numify(),-($BASE-1)); # +0 is to protect from 1e15 vs 100000000 (stupid to_string aaaarglburblll...) $x = $class->new($BASE); is ($x->numify()+0,$BASE+0); $x = $class->new(-$BASE); is ($x->numify(),-$BASE); $x = $class->new( -($BASE*$BASE*1+$BASE*1+1) ); is ($x->numify(),-($BASE*$BASE*1+$BASE*1+1)); ############################################################################### # test bug in _digits with length($c[-1]) where $c[-1] was "00001" instead of 1 $x = $class->new($BASE-2); $x++; $x++; $x++; $x++; if ($x > $BASE) { is (1,1) } else { is ("$x < $BASE","$x > $BASE"); } $x = $class->new($BASE+3); $x++; if ($x > $BASE) { is (1,1) } else { is ("$x > $BASE","$x < $BASE"); } # test for +0 instead of int(): $x = $class->new($MAX); is ($x->length(), length($MAX)); ############################################################################### # test bug that $class->digit($string) did not work is ($class->digit(123,2),1); ############################################################################### # bug in sub where number with at least 6 trailing zeros after any op failed $x = $class->new(123456); $z = $class->new(10000); $z *= 10; $x -= $z; is ($z, 100000); is ($x, 23456); ############################################################################### # bug in shortcut in mul() # construct a number with a zero-hole of BASE_LEN_SMALL { my @bl = $CL->_base_len(); my $bl = $bl[5]; $x = '1' x $bl . '0' x $bl . '1' x $bl . '0' x $bl; $y = '1' x (2*$bl); $x = $class->new($x)->bmul($y); # result is 123..$bl . $bl x (3*bl-1) . $bl...321 . '0' x $bl $y = ''; my $d = ''; for (my $i = 1; $i <= $bl; $i++) { $y .= $i; $d = $i.$d; } $y .= $bl x (3*$bl-1) . $d . '0' x $bl; is ($x,$y); ############################################################################# # see if mul shortcut for small numbers works $x = '9' x $bl; $x = $class->new($x); # 999 * 999 => 998 . 001, 9999*9999 => 9998 . 0001 is ($x*$x, '9' x ($bl-1) . '8' . '0' x ($bl-1) . '1'); } ############################################################################### # bug with rest "-0" in div, causing further div()s to fail $x = $class->new('-322056000'); ($x,$y) = $x->bdiv('-12882240'); is ($y,'0'); is_valid($y); # $y not '-0' ############################################################################### # bug in $x->bmod($y) # if $x < 0 and $y > 0 $x = $class->new('-629'); is ($x->bmod(5033),4404); ############################################################################### # bone/binf etc as plain calls (Lite failed them) is ($class->bzero(),0); is ($class->bone(),1); is ($class->bone('+'),1); is ($class->bone('-'),-1); is ($class->bnan(),'NaN'); is ($class->binf(),'inf'); is ($class->binf('+'),'inf'); is ($class->binf('-'),'-inf'); is ($class->binf('-inf'),'-inf'); ############################################################################### # is_one('-') is ($class->new(1)->is_one('-'),0); is ($class->new(-1)->is_one('-'),1); is ($class->new(1)->is_one(),1); is ($class->new(-1)->is_one(),0); ############################################################################### # [perl #30609] bug with $x -= $x not being 0, but 2*$x $x = $class->new(3); $x -= $x; is ($x, 0); $x = $class->new(-3); $x -= $x; is ($x, 0); $x = $class->new('NaN'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('inf'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('-inf'); $x -= $x; is ($x->is_nan(), 1); $x = $class->new('NaN'); $x += $x; is ($x->is_nan(), 1); $x = $class->new('inf'); $x += $x; is ($x->is_inf(), 1); $x = $class->new('-inf'); $x += $x; is ($x->is_inf('-'), 1); $x = $class->new(3); $x += $x; is ($x, 6); $x = $class->new(-3); $x += $x; is ($x, -6); $x = $class->new(3); $x *= $x; is ($x, 9); $x = $class->new(-3); $x *= $x; is ($x, 9); $x = $class->new(3); $x /= $x; is ($x, 1); $x = $class->new(-3); $x /= $x; is ($x, 1); $x = $class->new(3); $x %= $x; is ($x, 0); $x = $class->new(-3); $x %= $x; is ($x, 0); ############################################################################### # all tests done 1; ############################################################################### # sub to check validity of a BigInt internally, to ensure that no op leaves a # number object in an invalid state (f.i. "-0") sub is_valid { my ($x,$f) = @_; my $e = 0; # error? # allow the check to pass for all Lite, and all MBI and subclasses # ok as reference? $e = 'Not a reference to Math::BigInt' if ref($x) !~ /^Math::BigInt/; if (ref($x) ne 'Math::BigInt::Lite') { # has ok sign? $e = "Illegal sign $x->{sign} (expected: '+', '-', '-inf', '+inf' or 'NaN'" if $e eq '0' && $x->{sign} !~ /^(\+|-|\+inf|-inf|NaN)$/; $e = "-0 is invalid!" if $e ne '0' && $x->{sign} eq '-' && $x == 0; $e = $CALC->_check($x->{value}) if $e eq '0'; } # test done, see if error did crop up is (1,1), return if ($e eq '0'); is (1,$e." after op '$f'"); } __DATA__ &.= 1234:-345:1234-345 &+= 1:2:3 -1:-2:-3 &-= 1:2:-1 -1:-2:1 &*= 2:3:6 -1:5:-5 &%= 100:3:1 8:9:8 -629:5033:4404 &/= 100:3:33 -8:2:-4 &|= 2:1:3 &&= 5:7:5 &^= 5:7:2 &blog NaNlog:2:NaN 122:NaNlog:NaN NaNlog1:NaNlog:NaN 122:inf:NaN inf:122:NaN 122:-inf:NaN -inf:122:NaN -inf:-inf:NaN inf:inf:NaN 0:4:NaN -21:4:NaN 21:-21:NaN # normal results 1024:2:10 81:3:4 # 3.01.. truncate 82:3:4 # 3.9... truncate 80:3:3 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) 3:4:0 # $x == 1 => result 0 1:5:0 &is_negative 0:0 -1:1 1:0 +inf:0 -inf:1 NaNneg:0 &is_positive 0:0 -1:0 1:1 +inf:1 -inf:0 NaNneg:0 &is_int -inf:0 +inf:0 NaNis_int:0 1:1 0:1 123e12:1 &is_odd abc:0 0:0 1:1 3:1 -1:1 -3:1 10000001:1 10000002:0 2:0 120:0 121:1 &is_even abc:0 0:1 1:0 3:0 -1:0 -3:0 10000001:0 10000002:1 2:1 120:1 121:0 &bacmp +0:-0:0 +0:+1:-1 -1:+1:0 +1:-1:0 -1:+2:-1 +2:-1:1 -123456789:+987654321:-1 +123456789:-987654321:-1 +987654321:+123456789:1 -987654321:+123456789:1 -123:+4567889:-1 # NaNs acmpNaN:123: 123:acmpNaN: acmpNaN:acmpNaN: # infinity +inf:+inf:0 -inf:-inf:0 +inf:-inf:0 -inf:+inf:0 +inf:123:1 -inf:123:1 +inf:-123:1 -inf:-123:1 123:-inf:-1 -123:inf:-1 -123:-inf:-1 123:inf:-1 # return undef +inf:NaN: NaN:inf: -inf:NaN: NaN:-inf: &bnorm 0e999:0 0e-999:0 -0e999:0 -0e-999:0 123:123 # binary input 0babc:NaN 0b123:NaN 0b0:0 -0b0:0 -0b1:-1 0b0001:1 0b001:1 0b011:3 0b101:5 0b1001:9 0b10001:17 0b100001:33 0b1000001:65 0b10000001:129 0b100000001:257 0b1000000001:513 0b10000000001:1025 0b100000000001:2049 0b1000000000001:4097 0b10000000000001:8193 0b100000000000001:16385 0b1000000000000001:32769 0b10000000000000001:65537 0b100000000000000001:131073 0b1000000000000000001:262145 0b10000000000000000001:524289 0b100000000000000000001:1048577 0b1000000000000000000001:2097153 0b10000000000000000000001:4194305 0b100000000000000000000001:8388609 0b1000000000000000000000001:16777217 0b10000000000000000000000001:33554433 0b100000000000000000000000001:67108865 0b1000000000000000000000000001:134217729 0b10000000000000000000000000001:268435457 0b100000000000000000000000000001:536870913 0b1000000000000000000000000000001:1073741825 0b10000000000000000000000000000001:2147483649 0b100000000000000000000000000000001:4294967297 0b1000000000000000000000000000000001:8589934593 0b10000000000000000000000000000000001:17179869185 0b__101:NaN 0b1_0_1:5 0b0_0_0_1:1 # hex input -0x0:0 0xabcdefgh:NaN 0x1234:4660 0xabcdef:11259375 -0xABCDEF:-11259375 -0x1234:-4660 0x12345678:305419896 0x1_2_3_4_56_78:305419896 0xa_b_c_d_e_f:11259375 0x__123:NaN 0x9:9 0x11:17 0x21:33 0x41:65 0x81:129 0x101:257 0x201:513 0x401:1025 0x801:2049 0x1001:4097 0x2001:8193 0x4001:16385 0x8001:32769 0x10001:65537 0x20001:131073 0x40001:262145 0x80001:524289 0x100001:1048577 0x200001:2097153 0x400001:4194305 0x800001:8388609 0x1000001:16777217 0x2000001:33554433 0x4000001:67108865 0x8000001:134217729 0x10000001:268435457 0x20000001:536870913 0x40000001:1073741825 0x80000001:2147483649 0x100000001:4294967297 0x200000001:8589934593 0x400000001:17179869185 0x800000001:34359738369 # bug found by Mark Lakata in Calc.pm creating too big one-element numbers in _from_hex() 0x2dd59e18a125dbed30a6ab1d93e9c855569f44f75806f0645dc9a2e98b808c3:1295719234436071846486578237372801883390756472611551858964079371952886122691 # inf input inf:inf +inf:inf -inf:-inf 0inf:NaN # abnormal input :NaN abc:NaN 1 a:NaN 1bcd2:NaN 11111b:NaN +1z:NaN -1z:NaN # only one underscore between two digits _123:NaN _123_:NaN 123_:NaN 1__23:NaN 1E1__2:NaN 1_E12:NaN 1E_12:NaN 1_E_12:NaN +_1E12:NaN +0_1E2:100 +0_0_1E2:100 -0_0_1E2:-100 -0_0_1E+0_0_2:-100 E1:NaN E23:NaN 1.23E1:NaN 1.23E-1:NaN # bug with two E's in number being valid 1e2e3:NaN 1e2r:NaN 1e2.0:NaN # bug with two '.' in number being valid 1.2.2:NaN 1.2.3e1:NaN -1.2.3:NaN -1.2.3e-4:NaN 1.2e3.4:NaN 1.2e-3.4:NaN 1.2.3.4:NaN 1.2.t:NaN 1..2:NaN 1..2e1:NaN 1..2e1..1:NaN 12e1..1:NaN ..2:NaN .-2:NaN # leading zeros 012:12 0123:123 01234:1234 012345:12345 0123456:123456 01234567:1234567 012345678:12345678 0123456789:123456789 01234567891:1234567891 012345678912:12345678912 0123456789123:123456789123 01234567891234:1234567891234 # some inputs that result in zero 0e0:0 +0e0:0 +0e+0:0 -0e+0:0 0e-0:0 -0e-0:0 +0e-0:0 000:0 00e2:0 00e02:0 000e002:0 000e1230:0 00e-3:0 00e+3:0 00e-03:0 00e+03:0 -000:0 -00e2:0 -00e02:0 -000e002:0 -000e1230:0 -00e-3:0 -00e+3:0 -00e-03:0 -00e+03:0 # normal input 0:0 +0:0 +00:0 +000:0 000000000000000000:0 -0:0 -0000:0 +1:1 +01:1 +001:1 +00000100000:100000 123456789:123456789 -1:-1 -01:-1 -001:-1 -123456789:-123456789 -00000100000:-100000 1_2_3:123 10000000000E-1_0:1 1E2:100 1E1:10 1E0:1 1.23E2:123 100E-1:10 # floating point input # .2e2:20 1.E3:1000 1.01E2:101 1010E-1:101 -1010E0:-1010 -1010E1:-10100 1234.00:1234 # non-integer numbers -1010E-2:NaN -1.01E+1:NaN -1.01E-1:NaN &bnan 1:NaN 2:NaN abc:NaN &bone 2:+:1 2:-:-1 boneNaN:-:-1 boneNaN:+:1 2:abc:1 3::1 &binf 1:+:inf 2:-:-inf 3:abc:inf &is_nan 123:0 abc:1 NaN:1 -123:0 &is_inf +inf::1 -inf::1 abc::0 1::0 NaN::0 -1::0 +inf:-:0 +inf:+:1 -inf:-:1 -inf:+:0 -inf:-inf:1 -inf:+inf:0 +inf:-inf:0 +inf:+inf:1 # it must be exactly /^[+-]inf$/ +infinity::0 -infinity::0 &blsft abc:abc:NaN +2:+2:8 +1:+32:4294967296 +1:+48:281474976710656 +8:-2:NaN # excercise base 10 +12345:4:10:123450000 -1234:0:10:-1234 +1234:0:10:1234 +2:2:10:200 +12:2:10:1200 +1234:-3:10:NaN 1234567890123:12:10:1234567890123000000000000 -3:1:2:-6 -5:1:2:-10 -2:1:2:-4 -102533203:1:2:-205066406 &brsft abc:abc:NaN +8:+2:2 +4294967296:+32:1 +281474976710656:+48:1 +2:-2:NaN # excercise base 10 -1234:0:10:-1234 +1234:0:10:1234 +200:2:10:2 +1234:3:10:1 +1234:2:10:12 +1234:-3:10:NaN 310000:4:10:31 12300000:5:10:123 1230000000000:10:10:123 09876123456789067890:12:10:9876123 1234561234567890123:13:10:123456 820265627:1:2:410132813 # test shifting negative numbers in base 2 -15:1:2:-8 -14:1:2:-7 -13:1:2:-7 -12:1:2:-6 -11:1:2:-6 -10:1:2:-5 -9:1:2:-5 -8:1:2:-4 -7:1:2:-4 -6:1:2:-3 -5:1:2:-3 -4:1:2:-2 -3:1:2:-2 -2:1:2:-1 -1:1:2:-1 -1640531254:2:2:-410132814 -1640531254:1:2:-820265627 -820265627:1:2:-410132814 -205066405:1:2:-102533203 &bsstr +inf:inf -inf:-inf 1e+34:1e+34 123.456E3:123456e+0 100:1e+2 bsstrabc:NaN -5:-5e+0 -100:-1e+2 &numify numifyabc:NaN +inf:inf -inf:-inf 5:5 -5:-5 100:100 -100:-100 &bneg bnegNaN:NaN +inf:-inf -inf:inf abd:NaN 0:0 1:-1 -1:1 +123456789:-123456789 -123456789:123456789 &babs babsNaN:NaN +inf:inf -inf:inf 0:0 1:1 -1:1 +123456789:123456789 -123456789:123456789 &bsgn NaN:NaN +inf:1 -inf:-1 0:0 +123456789:1 -123456789:-1 &bcmp bcmpNaN:bcmpNaN: bcmpNaN:0: 0:bcmpNaN: 0:0:0 -1:0:-1 0:-1:1 1:0:1 0:1:-1 -1:1:-1 1:-1:1 -1:-1:0 1:1:0 123:123:0 123:12:1 12:123:-1 -123:-123:0 -123:-12:-1 -12:-123:1 123:124:-1 124:123:1 -123:-124:1 -124:-123:-1 100:5:1 -123456789:987654321:-1 +123456789:-987654321:1 -987654321:123456789:-1 -inf:5432112345:-1 +inf:5432112345:1 -inf:-5432112345:-1 +inf:-5432112345:1 +inf:+inf:0 -inf:-inf:0 +inf:-inf:1 -inf:+inf:-1 5:inf:-1 5:inf:-1 -5:-inf:1 -5:-inf:1 # return undef +inf:NaN: NaN:inf: -inf:NaN: NaN:-inf: &binc abc:NaN +inf:inf -inf:-inf +0:1 +1:2 -1:0 &bdec abc:NaN +inf:inf -inf:-inf +0:-1 +1:0 -1:-2 &badd abc:abc:NaN abc:0:NaN +0:abc:NaN +inf:-inf:NaN -inf:+inf:NaN +inf:+inf:inf -inf:-inf:-inf baddNaN:+inf:NaN baddNaN:+inf:NaN +inf:baddNaN:NaN -inf:baddNaN:NaN 0:0:0 1:0:1 0:1:1 1:1:2 -1:0:-1 0:-1:-1 -1:-1:-2 -1:+1:0 +1:-1:0 +9:+1:10 +99:+1:100 +999:+1:1000 +9999:+1:10000 +99999:+1:100000 +999999:+1:1000000 +9999999:+1:10000000 +99999999:+1:100000000 +999999999:+1:1000000000 +9999999999:+1:10000000000 +99999999999:+1:100000000000 +10:-1:9 +100:-1:99 +1000:-1:999 +10000:-1:9999 +100000:-1:99999 +1000000:-1:999999 +10000000:-1:9999999 +100000000:-1:99999999 +1000000000:-1:999999999 +10000000000:-1:9999999999 +123456789:987654321:1111111110 -123456789:987654321:864197532 -123456789:-987654321:-1111111110 +123456789:-987654321:-864197532 -1:10001:10000 -1:100001:100000 -1:1000001:1000000 -1:10000001:10000000 -1:100000001:100000000 -1:1000000001:1000000000 -1:10000000001:10000000000 -1:100000000001:100000000000 -1:1000000000001:1000000000000 -1:10000000000001:10000000000000 -1:-10001:-10002 -1:-100001:-100002 -1:-1000001:-1000002 -1:-10000001:-10000002 -1:-100000001:-100000002 -1:-1000000001:-1000000002 -1:-10000000001:-10000000002 -1:-100000000001:-100000000002 -1:-1000000000001:-1000000000002 -1:-10000000000001:-10000000000002 &bsub abc:abc:NaN abc:+0:NaN +0:abc:NaN +inf:-inf:inf -inf:+inf:-inf +inf:+inf:NaN -inf:-inf:NaN +0:+0:0 +1:+0:1 +0:+1:-1 +1:+1:0 -1:+0:-1 +0:-1:1 -1:-1:0 -1:+1:-2 +1:-1:2 +9:+1:8 +99:+1:98 +999:+1:998 +9999:+1:9998 +99999:+1:99998 +999999:+1:999998 +9999999:+1:9999998 +99999999:+1:99999998 +999999999:+1:999999998 +9999999999:+1:9999999998 +99999999999:+1:99999999998 +10:-1:11 +100:-1:101 +1000:-1:1001 +10000:-1:10001 +100000:-1:100001 +1000000:-1:1000001 +10000000:-1:10000001 +100000000:-1:100000001 +1000000000:-1:1000000001 +10000000000:-1:10000000001 +123456789:+987654321:-864197532 -123456789:+987654321:-1111111110 -123456789:-987654321:864197532 +123456789:-987654321:1111111110 10001:1:10000 100001:1:100000 1000001:1:1000000 10000001:1:10000000 100000001:1:100000000 1000000001:1:1000000000 10000000001:1:10000000000 100000000001:1:100000000000 1000000000001:1:1000000000000 10000000000001:1:10000000000000 10001:-1:10002 100001:-1:100002 1000001:-1:1000002 10000001:-1:10000002 100000001:-1:100000002 1000000001:-1:1000000002 10000000001:-1:10000000002 100000000001:-1:100000000002 1000000000001:-1:1000000000002 10000000000001:-1:10000000000002 &bmuladd abc:abc:0:NaN abc:+0:0:NaN +0:abc:0:NaN +0:0:abc:NaN NaNmul:+inf:0:NaN NaNmul:-inf:0:NaN -inf:NaNmul:0:NaN +inf:NaNmul:0:NaN +inf:+inf:0:inf +inf:-inf:0:-inf -inf:+inf:0:-inf -inf:-inf:0:inf +0:+0:0:0 +0:+1:0:0 +1:+0:0:0 +0:-1:0:0 -1:+0:0:0 123456789123456789:0:0:0 0:123456789123456789:0:0 -1:-1:0:1 -1:-1:0:1 -1:+1:0:-1 +1:-1:0:-1 +1:+1:0:1 +2:+3:0:6 -2:+3:0:-6 +2:-3:0:-6 -2:-3:0:6 111:111:0:12321 10101:10101:0:102030201 1001001:1001001:0:1002003002001 100010001:100010001:0:10002000300020001 10000100001:10000100001:0:100002000030000200001 11111111111:9:0:99999999999 22222222222:9:0:199999999998 33333333333:9:0:299999999997 44444444444:9:0:399999999996 55555555555:9:0:499999999995 66666666666:9:0:599999999994 77777777777:9:0:699999999993 88888888888:9:0:799999999992 99999999999:9:0:899999999991 11111111111:9:1:100000000000 22222222222:9:1:199999999999 33333333333:9:1:299999999998 44444444444:9:1:399999999997 55555555555:9:1:499999999996 66666666666:9:1:599999999995 77777777777:9:1:699999999994 88888888888:9:1:799999999993 99999999999:9:1:899999999992 -3:-4:-5:7 3:-4:-5:-17 -3:4:-5:-17 3:4:-5:7 -3:4:5:-7 3:-4:5:-7 9999999999999999999:10000000000000000000:1234567890:99999999999999999990000000001234567890 2:3:12345678901234567890:12345678901234567896 &bmul abc:abc:NaN abc:+0:NaN +0:abc:NaN NaNmul:+inf:NaN NaNmul:-inf:NaN -inf:NaNmul:NaN +inf:NaNmul:NaN +inf:+inf:inf +inf:-inf:-inf -inf:+inf:-inf -inf:-inf:inf +0:+0:0 +0:+1:0 +1:+0:0 +0:-1:0 -1:+0:0 123456789123456789:0:0 0:123456789123456789:0 -1:-1:1 -1:+1:-1 +1:-1:-1 +1:+1:1 +2:+3:6 -2:+3:-6 +2:-3:-6 -2:-3:6 111:111:12321 10101:10101:102030201 1001001:1001001:1002003002001 100010001:100010001:10002000300020001 10000100001:10000100001:100002000030000200001 11111111111:9:99999999999 22222222222:9:199999999998 33333333333:9:299999999997 44444444444:9:399999999996 55555555555:9:499999999995 66666666666:9:599999999994 77777777777:9:699999999993 88888888888:9:799999999992 99999999999:9:899999999991 +25:+25:625 +12345:+12345:152399025 +99999:+11111:1111088889 9999:10000:99990000 99999:100000:9999900000 999999:1000000:999999000000 9999999:10000000:99999990000000 99999999:100000000:9999999900000000 999999999:1000000000:999999999000000000 9999999999:10000000000:99999999990000000000 99999999999:100000000000:9999999999900000000000 999999999999:1000000000000:999999999999000000000000 9999999999999:10000000000000:99999999999990000000000000 99999999999999:100000000000000:9999999999999900000000000000 999999999999999:1000000000000000:999999999999999000000000000000 9999999999999999:10000000000000000:99999999999999990000000000000000 99999999999999999:100000000000000000:9999999999999999900000000000000000 999999999999999999:1000000000000000000:999999999999999999000000000000000000 9999999999999999999:10000000000000000000:99999999999999999990000000000000000000 &bdiv-list 100:20:5,0 4095:4095:1,0 -4095:-4095:1,0 4095:-4095:-1,0 -4095:4095:-1,0 123:2:61,1 9:5:1,4 9:4:2,1 # inf handling and general remainder 5:8:0,5 0:8:0,0 11:2:5,1 11:-2:-5,-1 -11:2:-5,1 # see table in documentation in MBI 0:inf:0,0 0:-inf:0,0 5:inf:0,5 5:-inf:0,5 -5:inf:0,-5 -5:-inf:0,-5 inf:5:inf,0 -inf:5:-inf,0 inf:-5:-inf,0 -inf:-5:inf,0 5:5:1,0 -5:-5:1,0 inf:inf:NaN,NaN -inf:-inf:NaN,NaN -inf:inf:NaN,NaN inf:-inf:NaN,NaN 8:0:inf,8 inf:0:inf,inf # exceptions to remainder rule -8:0:-inf,-8 -inf:0:-inf,-inf 0:0:NaN,NaN # test the shortcut in Calc if @$x == @$yorg 1234567812345678:123456712345678:10,688888898 12345671234567:1234561234567:10,58888897 123456123456:12345123456:10,4888896 1234512345:123412345:10,388895 1234567890999999999:1234567890:1000000000,999999999 1234567890000000000:1234567890:1000000000,0 1234567890999999999:9876543210:124999998,9503086419 1234567890000000000:9876543210:124999998,8503086420 96969696969696969696969696969678787878626262626262626262626262:484848484848484848484848486666666666666689898989898989898989:199,484848484848484848484848123012121211954972727272727272727451 # bug in v1.76 1267650600228229401496703205375:1267650600228229401496703205376:0,1267650600228229401496703205375 # excercise shortcut for numbers of the same length in div 999999999999999999999999999999999:999999999999999999999999999999999:1,0 999999999999999999999999999999999:888888888888888888888888888888888:1,111111111111111111111111111111111 999999999999999999999999999999999:777777777777777777777777777777777:1,222222222222222222222222222222222 999999999999999999999999999999999:666666666666666666666666666666666:1,333333333333333333333333333333333 999999999999999999999999999999999:555555555555555555555555555555555:1,444444444444444444444444444444444 999999999999999999999999999999999:444444444444444444444444444444444:2,111111111111111111111111111111111 999999999999999999999999999999999:333333333333333333333333333333333:3,0 999999999999999999999999999999999:222222222222222222222222222222222:4,111111111111111111111111111111111 999999999999999999999999999999999:111111111111111111111111111111111:9,0 9999999_9999999_9999999_9999999:3333333_3333333_3333333_3333333:3,0 9999999_9999999_9999999_9999999:3333333_0000000_0000000_0000000:3,999999999999999999999 9999999_9999999_9999999_9999999:3000000_0000000_0000000_0000000:3,999999999999999999999999999 9999999_9999999_9999999_9999999:2000000_0000000_0000000_0000000:4,1999999999999999999999999999 9999999_9999999_9999999_9999999:1000000_0000000_0000000_0000000:9,999999999999999999999999999 9999999_9999999_9999999_9999999:100000_0000000_0000000_0000000:99,99999999999999999999999999 9999999_9999999_9999999_9999999:10000_0000000_0000000_0000000:999,9999999999999999999999999 9999999_9999999_9999999_9999999:1000_0000000_0000000_0000000:9999,999999999999999999999999 9999999_9999999_9999999_9999999:100_0000000_0000000_0000000:99999,99999999999999999999999 9999999_9999999_9999999_9999999:10_0000000_0000000_0000000:999999,9999999999999999999999 9999999_9999999_9999999_9999999:1_0000000_0000000_0000000:9999999,999999999999999999999 &bdiv abc:abc:NaN abc:1:NaN 1:abc:NaN 0:0:NaN # inf handling (see table in doc) 0:inf:0 0:-inf:0 5:inf:0 5:-inf:0 -5:inf:0 -5:-inf:0 inf:5:inf -inf:5:-inf inf:-5:-inf -inf:-5:inf 5:5:1 -5:-5:1 inf:inf:NaN -inf:-inf:NaN -inf:inf:NaN inf:-inf:NaN 8:0:inf inf:0:inf -8:0:-inf -inf:0:-inf 0:0:NaN 11:2:5 -11:-2:5 -11:2:-5 11:-2:-5 0:1:0 0:-1:0 1:1:1 -1:-1:1 1:-1:-1 -1:1:-1 1:2:0 2:1:2 1:26:0 1000000000:9:111111111 2000000000:9:222222222 3000000000:9:333333333 4000000000:9:444444444 5000000000:9:555555555 6000000000:9:666666666 7000000000:9:777777777 8000000000:9:888888888 9000000000:9:1000000000 35500000:113:314159 71000000:226:314159 106500000:339:314159 1000000000:3:333333333 +10:+5:2 +100:+4:25 +1000:+8:125 +10000:+16:625 999999999999:9:111111111111 999999999999:99:10101010101 999999999999:999:1001001001 999999999999:9999:100010001 999999999999999:99999:10000100001 +1111088889:99999:11111 -5:-3:1 -5:3:-1 4:3:1 4:-3:-1 1:3:0 1:-3:0 -2:-3:0 -2:3:0 8:3:2 -8:3:-2 14:-3:-4 -14:3:-4 -14:-3:4 14:3:4 # bug in Calc with '99999' vs $BASE-1 10000000000000000000000000000000000000000000000000000000000000000000000000000000000:10000000375084540248994272022843165711074:999999962491547381984643365663244474111576 # test the shortcut in Calc if @$x == @$yorg 1234567812345678:123456712345678:10 12345671234567:1234561234567:10 123456123456:12345123456:10 1234512345:123412345:10 1234567890999999999:1234567890:1000000000 1234567890000000000:1234567890:1000000000 1234567890999999999:9876543210:124999998 1234567890000000000:9876543210:124999998 96969696969696969696969696969678787878626262626262626262626262:484848484848484848484848486666666666666689898989898989898989:199 # bug up to v0.35 in Calc (--$q one too many) 84696969696969696956565656566184292929292929292847474747436308080808080808086765396464646464646465:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999999 84696969696969696943434343434871161616161616161452525252486813131313131313143230042929292929292930:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999998 84696969696969696969696969697497424242424242424242424242385803030303030303030300750000000000000000:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6450000000000000000 84696969696969696930303030303558030303030303030057575757537318181818181818199694689393939393939395:13131313131313131313131313131394949494949494949494949494943535353535353535353535:6449999999999999997 # exercise shortcut for numbers of the same length in div 999999999999999999999999999999999:999999999999999999999999999999999:1 999999999999999999999999999999999:888888888888888888888888888888888:1 999999999999999999999999999999999:777777777777777777777777777777777:1 999999999999999999999999999999999:666666666666666666666666666666666:1 999999999999999999999999999999999:555555555555555555555555555555555:1 999999999999999999999999999999999:444444444444444444444444444444444:2 999999999999999999999999999999999:333333333333333333333333333333333:3 999999999999999999999999999999999:222222222222222222222222222222222:4 999999999999999999999999999999999:111111111111111111111111111111111:9 9999999_9999999_9999999_9999999:3333333_3333333_3333333_3333333:3 9999999_9999999_9999999_9999999:3333333_0000000_0000000_0000000:3 9999999_9999999_9999999_9999999:3000000_0000000_0000000_0000000:3 9999999_9999999_9999999_9999999:2000000_0000000_0000000_0000000:4 9999999_9999999_9999999_9999999:1000000_0000000_0000000_0000000:9 9999999_9999999_9999999_9999999:100000_0000000_0000000_0000000:99 9999999_9999999_9999999_9999999:10000_0000000_0000000_0000000:999 9999999_9999999_9999999_9999999:1000_0000000_0000000_0000000:9999 9999999_9999999_9999999_9999999:100_0000000_0000000_0000000:99999 9999999_9999999_9999999_9999999:10_0000000_0000000_0000000:999999 9999999_9999999_9999999_9999999:1_0000000_0000000_0000000:9999999 # bug with shortcut in Calc 0.44 949418181818187070707070707070707070:181818181853535353535353535353535353:5 &bmodinv # format: number:modulus:result # bmodinv Data errors abc:abc:NaN abc:5:NaN 5:abc:NaN # bmodinv Expected Results from normal use 1:5:1 3:5:2 3:-5:-3 -2:5:2 8:5033:4404 1234567891:13:6 -1234567891:13:7 324958749843759385732954874325984357439658735983745:2348249874968739:1741662881064902 -2:1:0 -1:1:0 0:1:0 1:1:0 2:1:0 3:1:0 4:1:0 -2:3:1 -1:3:2 0:3:NaN 1:3:1 2:3:2 3:3:NaN 4:3:1 -2:4:NaN -1:4:3 0:4:NaN 1:4:1 2:4:NaN 3:4:3 4:4:NaN ## bmodinv Error cases / useless use of function inf:5:NaN 5:inf:NaN -inf:5:NaN 5:-inf:NaN &bmodpow # format: number:exponent:modulus:result # bmodpow Data errors abc:abc:abc:NaN 5:abc:abc:NaN abc:5:abc:NaN abc:abc:5:NaN 5:5:abc:NaN 5:abc:5:NaN abc:5:5:NaN 3:5:0:NaN # bmodpow Expected results 0:0:2:1 1:0:2:1 0:3:5:0 -2:-2:1:0 -1:-2:1:0 0:-2:1:0 1:-2:1:0 2:-2:1:0 3:-2:1:0 4:-2:1:0 -2:-1:1:0 -1:-1:1:0 0:-1:1:0 1:-1:1:0 2:-1:1:0 3:-1:1:0 4:-1:1:0 -2:0:1:0 -1:0:1:0 0:0:1:0 1:0:1:0 2:0:1:0 3:0:1:0 4:0:1:0 -2:1:1:0 -1:1:1:0 0:1:1:0 1:1:1:0 2:1:1:0 3:1:1:0 4:1:1:0 -2:2:1:0 -1:2:1:0 0:2:1:0 1:2:1:0 2:2:1:0 3:2:1:0 4:2:1:0 -2:3:1:0 -1:3:1:0 0:3:1:0 1:3:1:0 2:3:1:0 3:3:1:0 4:3:1:0 -2:4:1:0 -1:4:1:0 0:4:1:0 1:4:1:0 2:4:1:0 3:4:1:0 4:4:1:0 -2:-2:3:1 -1:-2:3:1 0:-2:3:NaN 1:-2:3:1 2:-2:3:1 3:-2:3:NaN 4:-2:3:1 -2:-1:3:1 -1:-1:3:2 0:-1:3:NaN 1:-1:3:1 2:-1:3:2 3:-1:3:NaN 4:-1:3:1 -2:0:3:1 -1:0:3:1 0:0:3:1 1:0:3:1 2:0:3:1 3:0:3:1 4:0:3:1 -2:1:3:1 -1:1:3:2 0:1:3:0 1:1:3:1 2:1:3:2 3:1:3:0 4:1:3:1 -2:2:3:1 -1:2:3:1 0:2:3:0 1:2:3:1 2:2:3:1 3:2:3:0 4:2:3:1 -2:3:3:1 -1:3:3:2 0:3:3:0 1:3:3:1 2:3:3:2 3:3:3:0 4:3:3:1 -2:4:3:1 -1:4:3:1 0:4:3:0 1:4:3:1 2:4:3:1 3:4:3:0 4:4:3:1 -2:-2:4:NaN -1:-2:4:1 0:-2:4:NaN 1:-2:4:1 2:-2:4:NaN 3:-2:4:1 4:-2:4:NaN -2:-1:4:NaN -1:-1:4:3 0:-1:4:NaN 1:-1:4:1 2:-1:4:NaN 3:-1:4:3 4:-1:4:NaN -2:0:4:1 -1:0:4:1 0:0:4:1 1:0:4:1 2:0:4:1 3:0:4:1 4:0:4:1 -2:1:4:2 -1:1:4:3 0:1:4:0 1:1:4:1 2:1:4:2 3:1:4:3 4:1:4:0 -2:2:4:0 -1:2:4:1 0:2:4:0 1:2:4:1 2:2:4:0 3:2:4:1 4:2:4:0 -2:3:4:0 -1:3:4:3 0:3:4:0 1:3:4:1 2:3:4:0 3:3:4:3 4:3:4:0 -2:4:4:0 -1:4:4:1 0:4:4:0 1:4:4:1 2:4:4:0 3:4:4:1 4:4:4:0 8:-1:16:NaN 8:-1:5033:4404 8:7:5032:3840 8:8:-5:-4 1e50:1:1:0 98436739867439843769485798542749827593285729587325:43698764986460981048259837659386739857456983759328457:6943857329857295827698367:3104744730915914415259518 # bmodpow Error cases inf:5:13:NaN 5:inf:13:NaN &bmod # inf handling, see table in doc 0:inf:0 0:-inf:0 5:inf:5 5:-inf:5 -5:inf:-5 -5:-inf:-5 inf:5:0 -inf:5:0 inf:-5:0 -inf:-5:0 5:5:0 -5:-5:0 inf:inf:NaN -inf:-inf:NaN -inf:inf:NaN inf:-inf:NaN 8:0:8 inf:0:inf # exceptions to remainder rule -inf:0:-inf -8:0:-8 0:0:NaN abc:abc:NaN abc:1:abc:NaN 1:abc:NaN 0:0:NaN 0:1:0 1:0:1 0:-1:0 -1:0:-1 1:1:0 -1:-1:0 1:-1:0 -1:1:0 1:2:1 2:1:0 1000000000:9:1 2000000000:9:2 3000000000:9:3 4000000000:9:4 5000000000:9:5 6000000000:9:6 7000000000:9:7 8000000000:9:8 9000000000:9:0 35500000:113:33 71000000:226:66 106500000:339:99 1000000000:3:1 10:5:0 100:4:0 1000:8:0 10000:16:0 999999999999:9:0 999999999999:99:0 999999999999:999:0 999999999999:9999:0 999999999999999:99999:0 -9:+5:1 +9:-5:-1 -9:-5:-4 -5:3:1 -2:3:1 4:3:1 1:3:1 -5:-3:-2 -2:-3:-2 4:-3:-2 1:-3:-2 4095:4095:0 100041000510123:3:0 152403346:12345:4321 9:5:4 # test shortcuts in Calc # 1ex % 9 is always == 1, 1ex % 113 is != 1 for x = (4..9), 1ex % 10 = 0 1234:9:1 123456:9:3 12345678:9:0 1234567891:9:1 123456789123:9:6 12345678912345:9:6 1234567891234567:9:1 123456789123456789:9:0 1234:10:4 123456:10:6 12345678:10:8 1234567891:10:1 123456789123:10:3 12345678912345:10:5 1234567891234567:10:7 123456789123456789:10:9 1234:113:104 123456:113:60 12345678:113:89 1234567891:113:64 123456789123:113:95 12345678912345:113:53 1234567891234567:113:56 123456789123456789:113:39 # bug in bmod() not modifying the variable in place -629:5033:4404 # bug in bmod() in Calc in the _div_use_div() shortcut code path, # when X == X and X was big 111111111111111111111111111111:111111111111111111111111111111:0 12345678901234567890:12345678901234567890:0 &bgcd inf:12:NaN -inf:12:NaN 12:inf:NaN 12:-inf:NaN inf:inf:NaN inf:-inf:NaN -inf:-inf:NaN abc:abc:NaN abc:+0:NaN +0:abc:NaN +0:+0:0 +0:+1:1 +1:+0:1 +1:+1:1 +2:+3:1 +3:+2:1 -3:+2:1 -3:-2:1 -144:-60:12 144:-60:12 144:60:12 100:625:25 4096:81:1 1034:804:2 27:90:56:1 27:90:54:9 &blcm abc:abc:NaN abc:+0:NaN +0:abc:NaN +0:+0:NaN +1:+0:0 +0:+1:0 +27:+90:270 +1034:+804:415668 &band abc:abc:NaN abc:0:NaN 0:abc:NaN 1:2:0 3:2:2 +8:+2:0 +281474976710656:0:0 +281474976710656:1:0 +281474976710656:+281474976710656:281474976710656 281474976710656:-1:281474976710656 -2:-3:-4 -1:-1:-1 -6:-6:-6 -7:-4:-8 -7:4:0 -4:7:4 # negative argument is bitwise shorter than positive [perl #26559] 30:-3:28 123:-1:123 # equal arguments are treated special, so also do some test with unequal ones 0xFFFF:0xFFFF:0x0xFFFF 0xFFFFFF:0xFFFFFF:0x0xFFFFFF 0xFFFFFFFF:0xFFFFFFFF:0x0xFFFFFFFF 0xFFFFFFFFFF:0xFFFFFFFFFF:0x0xFFFFFFFFFF 0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF 0xF0F0:0xF0F0:0x0xF0F0 0x0F0F:0x0F0F:0x0x0F0F 0xF0F0F0:0xF0F0F0:0x0xF0F0F0 0x0F0F0F:0x0F0F0F:0x0x0F0F0F 0xF0F0F0F0:0xF0F0F0F0:0x0xF0F0F0F0 0x0F0F0F0F:0x0F0F0F0F:0x0x0F0F0F0F 0xF0F0F0F0F0:0xF0F0F0F0F0:0x0xF0F0F0F0F0 0x0F0F0F0F0F:0x0F0F0F0F0F:0x0x0F0F0F0F0F 0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0x0xF0F0F0F0F0F0 0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0x0x0F0F0F0F0F0F 0x1F0F0F0F0F0F:0x3F0F0F0F0F0F:0x0x1F0F0F0F0F0F &bior abc:abc:NaN abc:0:NaN 0:abc:NaN 1:2:3 +8:+2:10 +281474976710656:0:281474976710656 +281474976710656:1:281474976710657 +281474976710656:281474976710656:281474976710656 -2:-3:-1 -1:-1:-1 -6:-6:-6 -7:4:-3 -4:7:-1 +281474976710656:-1:-1 30:-3:-1 30:-4:-2 300:-76:-68 -76:300:-68 # equal arguments are treated special, so also do some test with unequal ones 0xFFFF:0xFFFF:0x0xFFFF 0xFFFFFF:0xFFFFFF:0x0xFFFFFF 0xFFFFFFFF:0xFFFFFFFF:0x0xFFFFFFFF 0xFFFFFFFFFF:0xFFFFFFFFFF:0x0xFFFFFFFFFF 0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF 0:0xFFFF:0x0xFFFF 0:0xFFFFFF:0x0xFFFFFF 0:0xFFFFFFFF:0x0xFFFFFFFF 0:0xFFFFFFFFFF:0x0xFFFFFFFFFF 0:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF 0xFFFF:0:0x0xFFFF 0xFFFFFF:0:0x0xFFFFFF 0xFFFFFFFF:0:0x0xFFFFFFFF 0xFFFFFFFFFF:0:0x0xFFFFFFFFFF 0xFFFFFFFFFFFF:0:0x0xFFFFFFFFFFFF 0xF0F0:0xF0F0:0x0xF0F0 0x0F0F:0x0F0F:0x0x0F0F 0xF0F0:0x0F0F:0x0xFFFF 0xF0F0F0:0xF0F0F0:0x0xF0F0F0 0x0F0F0F:0x0F0F0F:0x0x0F0F0F 0x0F0F0F:0xF0F0F0:0x0xFFFFFF 0xF0F0F0F0:0xF0F0F0F0:0x0xF0F0F0F0 0x0F0F0F0F:0x0F0F0F0F:0x0x0F0F0F0F 0x0F0F0F0F:0xF0F0F0F0:0x0xFFFFFFFF 0xF0F0F0F0F0:0xF0F0F0F0F0:0x0xF0F0F0F0F0 0x0F0F0F0F0F:0x0F0F0F0F0F:0x0x0F0F0F0F0F 0x0F0F0F0F0F:0xF0F0F0F0F0:0x0xFFFFFFFFFF 0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0x0xF0F0F0F0F0F0 0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0x0x0F0F0F0F0F0F 0x0F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF 0x1F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF &bxor abc:abc:NaN abc:0:NaN 0:abc:NaN 1:2:3 +8:+2:10 +281474976710656:0:281474976710656 +281474976710656:1:281474976710657 +281474976710656:281474976710656:0 -2:-3:3 -1:-1:0 -6:-6:0 -7:4:-3 -4:7:-5 4:-7:-3 -4:-7:5 30:-3:-29 30:-4:-30 300:-76:-360 -76:300:-360 # equal arguments are treated special, so also do some test with unequal ones 0xFFFF:0xFFFF:0 0xFFFFFF:0xFFFFFF:0 0xFFFFFFFF:0xFFFFFFFF:0 0xFFFFFFFFFF:0xFFFFFFFFFF:0 0xFFFFFFFFFFFF:0xFFFFFFFFFFFF:0 0:0xFFFF:0x0xFFFF 0:0xFFFFFF:0x0xFFFFFF 0:0xFFFFFFFF:0x0xFFFFFFFF 0:0xFFFFFFFFFF:0x0xFFFFFFFFFF 0:0xFFFFFFFFFFFF:0x0xFFFFFFFFFFFF 0xFFFF:0:0x0xFFFF 0xFFFFFF:0:0x0xFFFFFF 0xFFFFFFFF:0:0x0xFFFFFFFF 0xFFFFFFFFFF:0:0x0xFFFFFFFFFF 0xFFFFFFFFFFFF:0:0x0xFFFFFFFFFFFF 0xF0F0:0xF0F0:0 0x0F0F:0x0F0F:0 0xF0F0:0x0F0F:0x0xFFFF 0xF0F0F0:0xF0F0F0:0 0x0F0F0F:0x0F0F0F:0 0x0F0F0F:0xF0F0F0:0x0xFFFFFF 0xF0F0F0F0:0xF0F0F0F0:0 0x0F0F0F0F:0x0F0F0F0F:0 0x0F0F0F0F:0xF0F0F0F0:0x0xFFFFFFFF 0xF0F0F0F0F0:0xF0F0F0F0F0:0 0x0F0F0F0F0F:0x0F0F0F0F0F:0 0x0F0F0F0F0F:0xF0F0F0F0F0:0x0xFFFFFFFFFF 0xF0F0F0F0F0F0:0xF0F0F0F0F0F0:0 0x0F0F0F0F0F0F:0x0F0F0F0F0F0F:0 0x0F0F0F0F0F0F:0xF0F0F0F0F0F0:0x0xFFFFFFFFFFFF &bnot abc:NaN +0:-1 +8:-9 +281474976710656:-281474976710657 -1:0 -2:1 -12:11 &digit 0:0:0 12:0:2 12:1:1 123:0:3 123:1:2 123:2:1 123:-1:1 123:-2:2 123:-3:3 123456:0:6 123456:1:5 123456:2:4 123456:3:3 123456:4:2 123456:5:1 123456:-1:1 123456:-2:2 123456:-3:3 100000:-3:0 100000:0:0 100000:1:0 &mantissa abc:NaN 1e4:1 2e0:2 123:123 -1:-1 -2:-2 +inf:inf -inf:-inf &exponent abc:NaN 1e4:4 2e0:0 123:0 -1:0 -2:0 0:1 +inf:inf -inf:inf &parts abc:NaN,NaN 1e4:1,4 2e0:2,0 123:123,0 -1:-1,0 -2:-2,0 0:0,1 +inf:inf,inf -inf:-inf,inf &bfac -1:NaN NaNfac:NaN +inf:inf -inf:NaN 0:1 1:1 2:2 3:6 4:24 5:120 6:720 7:5040 8:40320 9:362880 10:3628800 11:39916800 12:479001600 20:2432902008176640000 22:1124000727777607680000 69:171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000 &bpow abc:12:NaN 12:abc:NaN 0:0:1 0:1:0 0:2:0 0:-1:inf 0:-2:inf 1:0:1 1:1:1 1:2:1 1:3:1 1:-1:1 1:-2:1 1:-3:1 2:0:1 2:1:2 2:2:4 2:3:8 3:3:27 -2:2:4 -2:3:-8 -2:4:16 -2:5:-32 2:-1:NaN -2:-1:NaN 2:-2:NaN -2:-2:NaN # inf tests +inf:1234500012:inf -inf:1234500012:inf -inf:1234500013:-inf +inf:-12345000123:inf -inf:-12345000123:-inf # -inf * -inf = inf -inf:2:inf -inf:0:NaN -inf:-1:0 -inf:inf:NaN 2:inf:inf 2:-inf:0 0:inf:0 0:-inf:inf -1:-inf:NaN -1:inf:NaN -2:inf:NaN -2:-inf:0 NaN:inf:NaN NaN:-inf:NaN -inf:NaN:NaN inf:NaN:NaN inf:-inf:NaN 1:inf:1 1:-inf:1 # 1 ** -x => 1 / (1 ** x) -1:0:1 -2:0:1 -1:1:-1 -1:2:1 -1:3:-1 -1:4:1 -1:5:-1 -1:-1:-1 -1:-2:1 -1:-3:-1 -1:-4:1 10:2:100 10:3:1000 10:4:10000 10:5:100000 10:6:1000000 10:7:10000000 10:8:100000000 10:9:1000000000 10:20:100000000000000000000 123456:2:15241383936 -2:2:4 -2:3:-8 -2:4:16 -2:5:-32 -3:2:9 -3:3:-27 -3:4:81 -3:5:-243 &length 100:3 10:2 1:1 0:1 12345:5 10000000000000000:17 -123:3 215960156869840440586892398248:30 &broot # sqrt() +0:2:0 +1:2:1 -1:2:NaN # -$x ** (1/2) => -$y, but not in froot() -123:2:NaN +inf:2:inf -inf:2:NaN 2:2:1 -2:2:NaN 4:2:2 9:2:3 16:2:4 100:2:10 123:2:11 15241:2:123 144:2:12 12:2:3 0.49:2:0 0.0049:2:0 # invalid ones 1:NaN:NaN -1:NaN:NaN 0:NaN:NaN -inf:NaN:NaN +inf:NaN:NaN NaN:0:NaN NaN:2:NaN NaN:inf:NaN NaN:inf:NaN 12:-inf:NaN 12:inf:NaN +0:0:NaN +1:0:NaN -1:0:NaN -2:0:NaN -123.45:0:NaN +inf:0:NaN 12:1:12 -12:1:NaN 8:-1:NaN -8:-1:NaN # cubic root 8:3:2 -8:3:NaN # fourths root 16:4:2 81:4:3 # 2 ** 64 18446744073709551616:4:65536 18446744073709551616:8:256 18446744073709551616:16:16 18446744073709551616:32:4 18446744073709551616:64:2 18446744073709551616:128:1 # 213 ** 15 84274086103068221283760416414557757:15:213 # see t/bigroot.t for more tests &bsqrt 145:12 144:12 143:11 16:4 170:13 169:13 168:12 4:2 3:1 2:1 9:3 12:3 256:16 100000000:10000 4000000000000:2000000 152399026:12345 152399025:12345 152399024:12344 # 2 ** 64 => 2 ** 32 18446744073709551616:4294967296 84274086103068221283760416414557757:290299993288095377 1:1 0:0 -2:NaN -123:NaN Nan:NaN +inf:inf -inf:NaN # see t/biglog.t for more tests &bexp NaN:NaN inf:inf 1:2 2:7 &batan2 NaN:1:10:NaN NaN:NaN:10:NaN 1:NaN:10:NaN inf:1:14:1 -inf:1:14:-1 0:-inf:14:3 -1:-inf:14:-3 1:-inf:14:3 0:inf:14:0 inf:-inf:14:2 -inf:-inf:14:-2 # +- 0.78.... inf:+inf:14:0 -inf:+inf:14:0 1:5:13:0 1:5:14:0 0:0:10:0 0:1:14:0 0:2:14:0 1:0:14:1 5:0:14:1 -1:0:11:-1 -2:0:77:-1 2:0:77:1 -1:5:14:0 1:5:14:0 -1:8:14:0 1:8:14:0 -1:1:14:0 &bpi 77:3 +0:3 11:3 # see t/bignok.t for more tests &bnok +inf:10:inf NaN:NaN:NaN NaN:1:NaN 1:NaN:NaN 1:1:1 # k > n 1:2:0 2:3:0 # k < 0 1:-2:0 # 7 over 3 = 35 7:3:35 7:6:7 100:90:17310309456440 100:95:75287520 2:0:1 7:0:1 2:1:2 &bround $round_mode('trunc') 0:12:0 NaNbround:12:NaN +inf:12:inf -inf:12:-inf 1234:0:1234 1234:2:1200 123456:4:123400 123456:5:123450 123456:6:123456 +10123456789:5:10123000000 -10123456789:5:-10123000000 +10123456789:9:10123456700 -10123456789:9:-10123456700 +101234500:6:101234000 -101234500:6:-101234000 #+101234500:-4:101234000 #-101234500:-4:-101234000 $round_mode('zero') +20123456789:5:20123000000 -20123456789:5:-20123000000 +20123456789:9:20123456800 -20123456789:9:-20123456800 +201234500:6:201234000 -201234500:6:-201234000 #+201234500:-4:201234000 #-201234500:-4:-201234000 +12345000:4:12340000 -12345000:4:-12340000 $round_mode('+inf') +30123456789:5:30123000000 -30123456789:5:-30123000000 +30123456789:9:30123456800 -30123456789:9:-30123456800 +301234500:6:301235000 -301234500:6:-301234000 #+301234500:-4:301235000 #-301234500:-4:-301234000 +12345000:4:12350000 -12345000:4:-12340000 $round_mode('-inf') +40123456789:5:40123000000 -40123456789:5:-40123000000 +40123456789:9:40123456800 -40123456789:9:-40123456800 +401234500:6:401234000 +401234500:6:401234000 #-401234500:-4:-401235000 #-401234500:-4:-401235000 +12345000:4:12340000 -12345000:4:-12350000 $round_mode('odd') +50123456789:5:50123000000 -50123456789:5:-50123000000 +50123456789:9:50123456800 -50123456789:9:-50123456800 +501234500:6:501235000 -501234500:6:-501235000 #+501234500:-4:501235000 #-501234500:-4:-501235000 +12345000:4:12350000 -12345000:4:-12350000 $round_mode('even') +60123456789:5:60123000000 -60123456789:5:-60123000000 +60123456789:9:60123456800 -60123456789:9:-60123456800 +601234500:6:601234000 -601234500:6:-601234000 #+601234500:-4:601234000 #-601234500:-4:-601234000 #-601234500:-9:0 #-501234500:-9:0 #-601234500:-8:0 #-501234500:-8:0 +1234567:7:1234567 +1234567:6:1234570 +12345000:4:12340000 -12345000:4:-12340000 $round_mode('common') +60123456789:5:60123000000 +60123199999:5:60123000000 +60123299999:5:60123000000 +60123399999:5:60123000000 +60123499999:5:60123000000 +60123500000:5:60124000000 +60123600000:5:60124000000 +60123700000:5:60124000000 +60123800000:5:60124000000 +60123900000:5:60124000000 -60123456789:5:-60123000000 -60123199999:5:-60123000000 -60123299999:5:-60123000000 -60123399999:5:-60123000000 -60123499999:5:-60123000000 -60123500000:5:-60124000000 -60123600000:5:-60124000000 -60123700000:5:-60124000000 -60123800000:5:-60124000000 -60123900000:5:-60124000000 &is_zero 0:1 NaNzero:0 +inf:0 -inf:0 123:0 -1:0 1:0 &is_one 0:0 NaNone:0 +inf:0 -inf:0 1:1 2:0 -1:0 -2:0 # floor and ceil tests are pretty pointless in integer space...but play safe &bfloor 0:0 NaNfloor:NaN +inf:inf -inf:-inf -1:-1 -2:-2 2:2 3:3 abc:NaN &bceil NaNceil:NaN +inf:inf -inf:-inf 0:0 -1:-1 -2:-2 2:2 3:3 abc:NaN &as_hex 128:0x80 -128:-0x80 0:0x0 -0:0x0 1:0x1 0x123456789123456789:0x123456789123456789 +inf:inf -inf:-inf NaNas_hex:NaN &as_bin 128:0b10000000 -128:-0b10000000 0:0b0 -0:0b0 1:0b1 0b1010111101010101010110110110110110101:0b1010111101010101010110110110110110101 0x123456789123456789:0b100100011010001010110011110001001000100100011010001010110011110001001 +inf:inf -inf:-inf NaNas_bin:NaN Math-BigInt-GMP-1.37/t/bigintpm.t0000644005434300244210000000215311630076171016331 0ustar OSPJADomain Users#!/usr/bin/perl -w use strict; use Test::More tests => 3635 + 6; use Math::BigInt lib => 'Calc'; use vars qw ($scale $class $try $x $y $f @args $ans $ans1 $ans1_str $setup $CL); $class = "Math::BigInt"; $CL = "Math::BigInt::Calc"; ############################################################################# # from_hex(), from_bin() and from_oct() tests my $x = Math::BigInt->from_hex('0xcafe'); is ($x, "51966", 'from_hex() works'); $x = Math::BigInt->from_hex('0xcafebabedead'); is ($x, "223195403574957", 'from_hex() works with long numbers'); $x = Math::BigInt->from_bin('0b1001'); is ($x, "9", 'from_bin() works'); $x = Math::BigInt->from_bin('0b1001100110011001100110011001'); is ($x, "161061273", 'from_bin() works with big numbers'); $x = Math::BigInt->from_oct('0775'); is ($x, "509", 'from_oct() works'); $x = Math::BigInt->from_oct('07777777777777711111111222222222'); is ($x, "9903520314281112085086151826", 'from_oct() works with big numbers'); ############################################################################# # all the other tests require 't/bigintpm.inc'; # all tests here for sharing Math-BigInt-GMP-1.37/t/biglog.t0000644005434300244210000001530711536167336016001 0ustar OSPJADomain Users#!/usr/bin/perl -w # 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 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 Test::More tests => 70; use Math::BigFloat; use Math::BigInt; my $cl = "Math::BigInt"; ############################################################################# # test log($n) in BigInt (broken until 1.80) is ($cl->new(2)->blog(), '0', "blog(2)"); is ($cl->new(288)->blog(), '5',"blog(288)"); is ($cl->new(2000)->blog(), '7', "blog(2000)"); ############################################################################# # test exp($n) in BigInt is ($cl->new(1)->bexp(), '2', "bexp(1)"); is ($cl->new(2)->bexp(), '7',"bexp(2)"); is ($cl->new(3)->bexp(), '20', "bexp(3)"); ############################################################################# ############################################################################# # BigFloat tests ############################################################################# # test log(2, N) where N > 67 (broken until 1.82) $cl = "Math::BigFloat"; # These tests can take quite a while, but are nec. Maybe protect them with # some alarm()? # this triggers the calculation and caching of ln(2): ok ($cl->new(5)->blog(undef,71), '1.6094379124341003746007593332261876395256013542685177219126478914741790'); # if the cache was correct, we should get this result, fast: ok ($cl->new(2)->blog(undef,71), '0.69314718055994530941723212145817656807550013436025525412068000949339362'); ok ($cl->new(10)->blog(undef,71), '2.3025850929940456840179914546843642076011014886287729760333279009675726'); ok ($cl->new(21)->blog(undef,71), '3.0445224377234229965005979803657054342845752874046106401940844835750742'); ############################################################################# # 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 ok ($cl->new(-2)->blog(), 'NaN'); ok ($cl->new(-1)->blog(), 'NaN'); ok ($cl->new(-10)->blog(), 'NaN'); ok ($cl->new(-2,2)->blog(), 'NaN'); my $ten = $cl->new(10)->blog(); # 10 is cached (up to 75 digits) ok ($cl->new(10)->blog(), '2.302585092994045684017991454684364207601'); # 0.1 is using the cached value for log(10), too ok ($cl->new(0.1)->blog(), -$ten); ok ($cl->new(0.01)->blog(), -$ten * 2); ok ($cl->new(0.001)->blog(), -$ten * 3); ok ($cl->new(0.0001)->blog(), -$ten * 4); # also cached ok ($cl->new(2)->blog(), '0.6931471805599453094172321214581765680755'); ok ($cl->new(4)->blog(), $cl->new(2)->blog * 2); # These are still slow, so do them only to 10 digits ok ($cl->new('0.2')->blog(undef,10), '-1.609437912'); ok ($cl->new('0.3')->blog(undef,10), '-1.203972804'); ok ($cl->new('0.4')->blog(undef,10), '-0.9162907319'); ok ($cl->new('0.5')->blog(undef,10), '-0.6931471806'); ok ($cl->new('0.6')->blog(undef,10), '-0.5108256238'); ok ($cl->new('0.7')->blog(undef,10), '-0.3566749439'); ok ($cl->new('0.8')->blog(undef,10), '-0.2231435513'); ok ($cl->new('0.9')->blog(undef,10), '-0.1053605157'); ok ($cl->new('9')->blog(undef,10), '2.197224577'); ok ($cl->new('10')->blog(10,10), '1.000000000'); ok ($cl->new('20')->blog(20,10), '1.000000000'); ok ($cl->new('100')->blog(100,10), '1.000000000'); ok ($cl->new('100')->blog(10,10), '2.000000000'); # 10 ** 2 == 100 ok ($cl->new('400')->blog(20,10), '2.000000000'); # 20 ** 2 == 400 ok ($cl->new('4')->blog(2,10), '2.000000000'); # 2 ** 2 == 4 ok ($cl->new('16')->blog(2,10), '4.000000000'); # 2 ** 4 == 16 ok ($cl->new('1.2')->bpow('0.3',10), '1.056219968'); ok ($cl->new('10')->bpow('0.6',10), '3.981071706'); # blog should handle bigint input is (Math::BigFloat::blog(Math::BigInt->new(100),10), 2, "blog(100)"); ############################################################################# # some integer results is ($cl->new(2)->bpow(32)->blog(2), '32', "2 ** 32"); is ($cl->new(3)->bpow(32)->blog(3), '32', "3 ** 32"); is ($cl->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'); test_bpow ('0.2','0.41',10, '0.5169187652'); ############################################################################# # test bexp() with cached results is ($cl->new(1)->bexp(), '2.718281828459045235360287471352662497757', 'bexp(1)'); is ($cl->new(2)->bexp(40), $cl->new(1)->bexp(45)->bpow(2,40), 'bexp(2)'); is ($cl->new("12.5")->bexp(61), $cl->new(1)->bexp(65)->bpow(12.5,61), 'bexp(12.5)'); ############################################################################# # test bexp() with big values (non-cached) is ($cl->new(1)->bexp(100), '2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427', 'bexp(100)'); is ($cl->new("12.5")->bexp(91), $cl->new(1)->bexp(95)->bpow(12.5,91), 'bexp(12.5) to 91 digits'); # all done 1; ############################################################################# sub test_bpow { my ($x,$y,$scale,$result) = @_; print "# Tried: $x->bpow($y,$scale);\n" unless ok ($cl->new($x)->bpow($y,$scale),$result); } Math-BigInt-GMP-1.37/t/bigroot.t0000644005434300244210000000264411536167336016203 0ustar OSPJADomain Users#!/usr/bin/perl -w # 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; use Test::More tests => 4 * 2; use Math::BigFloat; use Math::BigInt; my $cl = "Math::BigFloat"; my $c = "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,$result) = @_; my $s = $scale || 'undef'; is ($cl->new($x)->bpow($n)->broot($y,$scale),$result, "Try: $cl $x->bpow($n)->broot($y,$s) == $result"); $result =~ s/\..*//; is ($c->new($x)->bpow($n)->broot($y,$scale),$result, "Try: $c $x->bpow($n)->broot($y,$s) == $result"); } Math-BigInt-GMP-1.37/t/storable.t0000644005434300244210000000040111523605317016326 0ustar OSPJADomain Usersuse strict; use warnings; use Test::More tests => 1; use Math::BigInt::GMP; use Storable qw(freeze thaw); my $num = Math::BigInt::GMP->_new(42); my $serialised = freeze $num; my $cloned = thaw $serialised; ok(!Math::BigInt::GMP->_acmp($cloned, $num)); Math-BigInt-GMP-1.37/t/threads.t0000644005434300244210000000114511523605317016153 0ustar OSPJADomain Usersuse strict; use warnings; use Test::More; use Config; BEGIN { plan skip_all => 'Perl compiled without ithreads' unless $Config{useithreads}; plan skip_all => 'ithreads support requires perl 5.8 or newer' unless $] >= 5.008000; plan tests => 22; } use threads; use Math::BigInt lib => 'GMP'; my @threads = map { my $x = $_; threads->create(sub { (Math::BigInt->new($x)) }); } 0 .. 19; my @ret = map { $_->join } @threads; pass 'we survived our threads'; is @ret, 20, 'got all the numbers we expected'; is($ret[$_], $_, 'numbers look sane') for 0 .. 19; Math-BigInt-GMP-1.37/TODO0000644005434300244210000000057411523747250014571 0ustar OSPJADomain Users* _lsft() and _rsft() could probably be a bit more optimized * move _log_int() to XS * _digit() should be in XS * _zeros() could be more optimized (divide by 1e5, check for == 0?) * replace all malloc() with New() and all free() with Savefree()? Please send me test-reports, your experiences with this and your ideas - I love to hear about my work! Tels Math-BigInt-GMP-1.37/typemap0000644005434300244210000000025611521227622015472 0ustar OSPJADomain Usersmpz_t * MPZ mpz_t_ornull * MPZ_NF INPUT MPZ $var = mpz_from_sv($arg); MPZ_NF $var = mpz_from_sv_nofail($arg); OUTPUT MPZ $arg = sv_from_mpz($var);