Math-BigInt-GMP-1.37/ 0000755 0054343 0024421 00000000000 11630745112 014065 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.37/BUGS 0000644 0054343 0024421 00000000330 11523750261 014546 0 ustar OSPJA Domain 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/ 0000755 0054343 0024421 00000000000 11630745101 015162 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.37/build/leak.pl 0000644 0054343 0024421 00000002400 11521227622 016431 0 ustar OSPJA Domain 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/leaktest 0000755 0054343 0024421 00000000173 11521227622 016727 0 ustar OSPJA Domain 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/README 0000644 0054343 0024421 00000000160 11521227622 016041 0 ustar OSPJA Domain Users This directory contains scripts that are used by the developers.
They are not necessarily usefull for users :)
Math-BigInt-GMP-1.37/CHANGES 0000644 0054343 0024421 00000035467 11630744134 015102 0 ustar OSPJA Domain Users Revision 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/CREDITS 0000644 0054343 0024421 00000000272 11523750122 015104 0 ustar OSPJA Domain 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.xs 0000644 0054343 0024421 00000053415 11523750266 015103 0 ustar OSPJA Domain 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/ 0000755 0054343 0024421 00000000000 11630745101 014634 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.37/inc/Devel/ 0000755 0054343 0024421 00000000000 11630745101 015673 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.37/inc/Devel/CheckLib.pm 0000444 0054343 0024421 00000033246 11547630462 017715 0 ustar OSPJA Domain 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