Math-BigInt-GMP-1.7003/ 0000755 4030723 4001001 00000000000 14770736211 014226 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.7003/BUGS 0000644 4030723 4001001 00000000530 13577457661 014724 0 ustar OSPJA Domain Users For an updated list of bugs, see
https://rt.cpan.org/Public/Dist/Display.html?Name=Math-BigInt-GMP
The following list is not up to date:
* 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.7003/build/ 0000755 4030723 4001001 00000000000 14770736174 015335 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.7003/build/leak.pl 0000755 4030723 4001001 00000002376 13577457607 016626 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.7003/build/leaktest 0000755 4030723 4001001 00000000172 13577457607 017104 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.7003/build/README 0000644 4030723 4001001 00000000160 13577456472 016216 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.7003/CHANGES 0000644 4030723 4001001 00000051635 14770724433 015236 0 ustar OSPJA Domain Users 1.7003 2025-03-25
* Sync test files with Math-BigInt.
1.7002 2025-02-22
* Sync test files with Math-BigInt.
1.7001 2024-01-06
* Sync test files with Math-BigInt.
1.7000 2023-12-29
* Add new methods _to_hex(), _to_bin(), _to_oct(), _lcm(), _dfac(), _nok(),
_fib(), and _lucas(). These are now in XS code rather than being inherited.
1.6014 2023-12-27
* Sync test files with Math-BigInt.
1.6013 2023-09-20
* Sync test files with Math-BigInt.
* Remove obsolete link to cpanratings.org.
1.6012 2023-04-03
* Sync test files with Math-BigInt.
1.6011 2022-05-17
* Sync test files with Math-BigInt.
1.6010 2021-12-29
* Add static gmp_version() function (code provided by FGasper on GitHub).
* Make t/01load.t display the output from gmp_version().
1.6009 2021-09-28
* Sync test files with Math-BigInt.
1.6008 2021-07-02
* Sync test files with Math-BigInt.
1.6007 2019-10-10
* Sync test files with Math-BigInt.
1.6006 2018-10-09
* Update MANIFEST.SKIP.
* Sync test files with Math-BigInt.
* Better Makefile.PL.
1.6005 2018-04-17
* Fix memory leak in _modinv() (thanks to DANAJ). See CPAN RT #123807.
* Make tests pass when '.' is not in @INC. (CPAN RT #120718)
* The tests now require Test::More version 0.88 or newer.
* Sync test files with Math-BigInt.
* Add test files t/release-test-version.t, t/release-portability.t, and
t/release-cpan-changes.t.
* Use a MANIFEST.SKIP file based on the default file in the ExtUtils-Manifest
distribution.
* Format CHANGES according to CPAN::Changes::Spec.
* Convert test file t/02pod.t to t/release-pod.t and t/03podcov.t to
t/release-pod-coverage.t.
1.6004 2017-02-05 pjacklam
* Fix typos in POD.
* Update link in SUPPORT section.
* Minor improvements to the documentation (POD).
1.6003 2017-01-11 pjacklam
* Fix syntax for required version of Math::BigInt::Lib.
* Better checking of POD coverage.
* Sync test files with Math-BigInt-1.999808.
1.6002 2016-12-03 pjacklam
* Use ExtUtils::MakeMaker rather than Module::Install in Makefile.PL
* Don't use Devel::CheckLib. It fails on Windows even in cases where
this distribution would build just fine.
* Update BUGS file.
* Remove author information in LICENSE file.
* Inform that the TODO file is not up to date.
* Remove INSTALL file. The information is in the README file.
1.6001 2016-11-23 pjacklam
* Sync test files with Math-BigInt-1.999801.
* Correct version number in CHANGES file.
1.6000 2016-11-15 pjacklam
* Sync test files with Math-BigInt-1.999800.
* Update bundled Devel::CheckLib from v1.03 to v1.07.
* Math::BigInt::GMP is now a subclass of Math::BigInt::Lib, so remove pure
Perl methods from Math::BigInt::GMP that are implemented in the superclass
Math::BigInt::Lib. The methods removed are _digit(), _num(), _nok(), and
_log_int(). The version of _log_int() implemented in Math::BigInt::GMP was
buggy anyway.
* Fix _check() so it doesn't give a "use of uninitialized value" warning if
given an undefined "object".
* Trim whitespace in all files.
* Better use of the functionality in Test::More in t/bigintg.t.
1.51 2016-04-25 pjacklam
* Sync test files with Math-BigInt-1.999719.
1.50 2016-04-22 pjacklam
* Sync test files with Math-BigInt-1.999718.
1.49 2016-01-03 pjacklam
* Sync test files with Math-BigInt-1.999714.
1.48 2015-12-31 pjacklam
* Sync test files with Math-BigInt-1.999713.
1.47 2015-12-14 pjacklam
* Add patch from Gregor Herrmann (GREGOA) based on code by Dana Jacobsen
(DANAJ) to fix problems with the new() method when Perl is compiled with
support for 64-bit integers, but on platforms when the underlying OS is
32-bit (CPAN RT #71548).
1.46 2015-12-03 pjacklam
* Add patch from Dana Jacobsen (DANAJ) and add new test file
't/mbi-from-big-scalar.t' regarding CPAN RT #103517.
* Fix spelling in GMP.xs ('modifing' -> 'modifying').
* Whitespace/formatting in t/bigintg.t to make it more readble (for me, at
least) and more in accordance with the 'perlstyle' manpage.
1.45 2015-11-09 pjacklam
* Sync test files with Math-BigInt-1.999709.
* Required version of Test::More is 0.47.
1.44 2015-10-29 pjacklam
* Sync test files with Math-BigInt-1.999707.
* Update the README file.
* Remove the files INSTALL and LICENSE as this information is already covered
in the file README.
* Replace 'use vars ...' with 'our ...'. We require a Perl newer than 5.6.0
anyway.
* Required version of Math-BigInt is now 1.999706.
* Add 'Test::More' to TEST_REQUIRES in Makefile.PL.
* Enable 'use warnings'. We require a Perl newer than 5.6.0 anyway.
* Add 'assertlib.*\.exe' to MANIFEST.SKIP, since make generates temporary
files like 'assertlibzxjE4WfG.exe' on Cygwin.
1.43 2015-09-21 pjacklam
* Sync test files with Math-BigInt-1.999703.
* Required version of Math-BigInt is now 1.999703.
* Update author information.
1.42 2015-09-17 pjacklam
* Sync test files with Math-BigInt-1.999702.
* Required version of Math-BigInt is now 1.999702.
1.41 2015-09-11 pjacklam
lib/Math/BigInt/GMP.pm
* Updated version number.
Makefile.PL
* Updated required version of Math::BigInt.
t/bigfltpm.inc
* Synced tests with the Math-BigInt distribution.
t/bigfltpm.t
* Updated number of tests.
t/bigintpm.inc
* Synced tests with the Math-BigInt distribution.
t/bigintpm.t
* Updated number of tests.
1.40 2015-08-18 pjacklam
CHANGES
* Add changes for the newest release.
* Reorder change entries into descending chronological order.
lib/Devel/CheckLib.pm
* Update bundled Devel::CheckLib from v1.01 to v1.03.
Makefile.PL
* Update required version of Math-BigInt to 1.9994.
t/01load.t
* Improve formatting of module version information.
t/bigfltpm.t
* Use the correct backend, in this case Math::BigInt::GMP.
* Skip test specific for the Math::BigInt::Calc backend.
t/bigintpm.inc
* Rather than an early exit(), use skip() to skip tests.
t/bigintpm.t
* Use the correct backend, in this case Math::BigInt::GMP.
t/biglog.t
* Use the correct backend, in this case Math::BigInt::GMP. This was correct
in v1.21, but has been wrong since then.
t/bigroot.t
* Use the correct backend, in this case Math::BigInt::GMP. This was correct
up until v1.32, but has been wrong since then.
lib/Math/BigInt/GMP.pm
* Increment Math::BigInt::GMP version number to 1.40.
1.39 2015-08-17 pjacklam
* Updated test files with those from Math-BigInt-1.9997.
1.38 2014-04-03 pjacklam
* Updated test files from the Math::BigInt distribution (Peter John Acklam).
* Updated POD (Peter John Acklam)
* Updated bundled Devel::CheckLib from v0.93 to v1.01 (Peter John Acklam).
1.37 2011-09-04 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)
1.36 2011-02-26 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).
1.35 2011-02-08 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).
1.34 2011-02-07 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).
1.33 2011-01-30 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).
1.32 2010-09-23 rafl 5559 tests
* Re-upload 1.31 as a stable release without further changes.
1.31 2010-09-21 rafl 5559 tests DEVELOPMENT RELEASE
* Add hooks for Storable (de-)serialisation.
* Avoid failure in the destructor if someone blessed nonsense into our class.
1.30 2010-09-20 rafl 5558 tests
* Re-upload 1.29 as a stable release without further changes.
1.29 2010-09-19 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.
1.28 2010-09-17 rafl 5558 tests
* Re-upload 1.27 without further changes as a stable release.
1.27 2010-09-15 rafl 5558 tests DEVELOPMENT RELEASE
* Try to support perls older than 5.8.8 again.
Tested with 5.8.7 and 5.6.2.
1.26 2010-09-14 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.
1.25 2010-09-10 rafl 5536 tests
* Fix tests with Math::BigInt >= 1.90 and depend on it.
1.24 2007-07-31 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!)
1.23 2007-07-25 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)!)
1.22 2007-06-01 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)
1.21 2007-04-17 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)
1.20 2007-04-09 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
1.19 2007-01-27 Tels 5339 tests
* add support for octal
* take over tests from MBI 1.78 and require it
1.18 2005-04-11 Tels 5186 tests
* _log_int() handles now plain scalars as $base parameter
* take over tests from MBI 1.76, require it
1.17 2005-01-01 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))
1.16 2004-12-09 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
1.15 2004-11-22 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
1.14 2004-02-15 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
1.13 2004-01-10 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)
1.12 2003-12-11 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
* testsuite from v1.65
* fixed prereq to require BigInt v1.65
* 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
1.11 2003-01-01 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
1.10 2002-12-24 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/
* 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
1.08 2002-12-12 Tels 4069 tests (never released)
* added implementation of bmodpow() using GMPs mpow_gmp()
* release signed by key http://bloodgate.com/tels.asc id 93B84C15
1.07 2002-07-07 Tels
* testsuite from BigInt v1.60 - 4054 tests
* fixed PREREQUISITES to BigInt v1.60
1.06 2002-03-23 Tels
* testsuite from v1.55 - 3874 tests
* fixed PREREQUISITES to Math::GMP v2.03, BigInt v1.55
* fixed typos in CHANGES
* added _from_bin()
1.05 2002-02-16 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.
1.04 2002-01-26 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
* _is_odd()/_is_even() use $two instead of 2: 5600 op/s instead of 4700
1.03 2001-11-01 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
1.02 2001-09-02 Tels
* removed auto-export and added empty import()
* taken over tests from BigInt v1.42
1.01 2001-08-06 Tels
* first release
* fixed all the bugs in v1.00
* taken over tests from BigInt v1.40
1.00 2001-07-22 Tels
* First version (basically working with some quirks)
Math-BigInt-GMP-1.7003/CREDITS 0000644 4030723 4001001 00000000272 13577456363 015262 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.7003/GMP.xs 0000644 4030723 4001001 00000062754 14543255660 015245 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) || SvIOK(x)) && (sizeof(UV) <= sizeof(unsigned long) || SvUV(x) == (unsigned long)SvUV(x)))
{
mpz_init_set_ui(*RETVAL, (unsigned long)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) || SvIOK(x)) && (sizeof(UV) <= sizeof(unsigned long) || SvUV(x) == (unsigned long)SvUV(x))) {
mpz_init_set_ui(*mpz, (unsigned long)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
##############################################################################
# _to_hex() - return ref to hexadecimal string (unprefixed)
SV *
_to_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);
RETVAL = newSV(len); /* alloc len bytes */
SvPOK_on(RETVAL);
buf = SvPVX(RETVAL); /* get ptr to storage */
mpz_get_str(buf, 16, *n); /* convert to hexadecimal string */
SvCUR_set(RETVAL, len); /* so set real length */
OUTPUT:
RETVAL
##############################################################################
# _to_bin() - return ref to binary string (unprefixed)
SV *
_to_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);
RETVAL = newSV(len); /* alloc len bytes */
SvPOK_on(RETVAL);
buf = SvPVX(RETVAL); /* get ptr to storage */
mpz_get_str(buf, 2, *n); /* convert to binary string */
SvCUR_set(RETVAL, len); /* so set real length */
OUTPUT:
RETVAL
##############################################################################
# _to_oct() - return ref to octal string (unprefixed)
SV *
_to_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);
RETVAL = newSV(len); /* alloc len bytes */
SvPOK_on(RETVAL);
buf = SvPVX(RETVAL); /* get ptr to storage */
mpz_get_str(buf, 8, *n); /* convert to octal string */
SvCUR_set(RETVAL, len); /* so set real length */
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 octal 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 );
mpz_clear(*RETVAL);
free(RETVAL);
}
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 );
##############################################################################
# _lcm() - lcm(m,n)
mpz_t *
_lcm(Class,x,y)
mpz_t* x
mpz_t* y
CODE:
NEW_GMP_MPZ_T_INIT;
mpz_lcm(*RETVAL, *x, *y);
OUTPUT:
RETVAL
##############################################################################
# _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
##############################################################################
# _nok() - n over k (binomial coefficient)
void
_nok(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_bin_ui(*TEMP, *TEMP, mpz_get_ui(*TEMP_1));
PUSHs( x );
##############################################################################
# _fib() - Fibonacci number
void
_fib(Class,x)
SV* x
PREINIT:
mpz_t* TEMP;
PPCODE:
GMP_GET_ARG_0; /* TEMP = x */
mpz_fib_ui(*TEMP, mpz_get_ui(*TEMP));
PUSHs( x );
##############################################################################
# _lucas() - Lucas number
void
_lucas(Class,x)
SV* x
PREINIT:
mpz_t* TEMP;
PPCODE:
GMP_GET_ARG_0; /* TEMP = x */
mpz_lucnum_ui(*TEMP, mpz_get_ui(*TEMP));
PUSHs( x );
##############################################################################
# _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 );
##############################################################################
# _dfac() - n!! (double factorial)
void
_dfac(Class,x)
SV* x
PREINIT:
mpz_t* TEMP;
PPCODE:
GMP_GET_ARG_0; /* TEMP = x */
mpz_2fac_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 );
##############################################################################
# gmp_version()
SV*
gmp_version()
CODE:
RETVAL = newSVpv(gmp_version, 0);
OUTPUT:
RETVAL
Math-BigInt-GMP-1.7003/inc/ 0000755 4030723 4001001 00000000000 14770736174 015007 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.7003/inc/Devel/ 0000755 4030723 4001001 00000000000 14770736174 016046 5 ustar OSPJA Domain Users Math-BigInt-GMP-1.7003/inc/Devel/CheckLib.pm 0000644 4030723 4001001 00000033246 12312561615 020042 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