Skip to content

Commit

Permalink
import Math-BigInt-GMP 1.17 from CPAN
Browse files Browse the repository at this point in the history
git-cpan-module:   Math-BigInt-GMP
git-cpan-version:  1.17
git-cpan-authorid: TELS
git-cpan-file:     authors/id/T/TE/TELS/math/Math-BigInt-GMP-1.17.tar.gz
  • Loading branch information
Tels authored and schwern committed Dec 12, 2009
1 parent f61845f commit 8d2e972
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 80 deletions.
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@
* 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))

Please send me test-reports, your experiences with this and your ideas - I love
to hear about my work!
Expand Down
65 changes: 35 additions & 30 deletions GMP.xs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ _num(Class, n)

##############################################################################
# _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)
Expand All @@ -163,30 +167,37 @@ _zeros(Class,n)
char *buf_end;

CODE:
/* len is always >= 1, and might be off (greater) by one than real len */
len = mpz_sizeinbase(*n, 10);
TEMP = newSV(len); /* alloc len +1 bytes */
SvPOK_on(TEMP); /* make an PV */
buf = SvPVX(TEMP); /* get ptr to storage */
buf_end = buf + len - 1; /* end of storage (-1)*/
mpz_get_str(buf, 10, *n); /* convert to decimal string */
RETVAL = 0;
if (*buf_end == 0)
{
buf_end--; /* ptr to last real digit */
len --; /* got one shorter than expected */
}
if (len > 1) /* '0' has not trailing zeross! */
/* odd numbers can not have trailing zeros */
RETVAL = 1 - mpz_tstbit(*n,0);

if (RETVAL != 0) /* was even */
{
while (len-- > 0)
/* len is always >= 1, and might be off (greater) by one than real len */
len = mpz_sizeinbase(*n, 10);
TEMP = newSV(len); /* alloc len +1 bytes */
SvPOK_on(TEMP); /* make an PV */
buf = SvPVX(TEMP); /* get ptr to storage */
buf_end = buf + len - 1; /* end of storage (-1)*/
mpz_get_str(buf, 10, *n); /* convert to decimal string */
RETVAL = 0;
if (*buf_end == 0) /* points to terminating zero? */
{
if (*buf_end-- != '0')
{
break;
}
RETVAL++;
buf_end--; /* ptr to last real digit */
len --; /* got one shorter than expected */
}
}
if (len > 1) /* '0' has not trailing zeross! */
{
while (len-- > 0) /* actually, we should hit a nonzero */
{ /* before the end */
if (*buf_end-- != '0')
{
break;
}
RETVAL++;
}
}
SvREFCNT_dec(TEMP); /* Bumpersticker: Free Temp! */
} /* end if n was even */
OUTPUT:
RETVAL

Expand Down Expand Up @@ -359,19 +370,13 @@ _sub(Class,x,y, ...)
PREINIT:
mpz_t* TEMP;
mpz_t* TEMP_1;
mpz_t* TEMP_2;
PPCODE:
GMP_GET_ARGS_0_1; /* (TEMP, TEMP_1) = (x,y) */
if ( items == 4 && SvTRUE(ST(3)) )
{
/* return new(y - x) */
/* need to create TEMP_2 or it will ssegfault */
TEMP_2 = malloc (sizeof(mpz_t)); mpz_init(*TEMP_2);

mpz_sub(*TEMP_2, *TEMP, *TEMP_1);

PUSHs(sv_setref_pv(sv_newmortal(), "Math::BigInt::GMP", (void*)TEMP_2));
/*PUSHs(sv_setref_pv(y, "Math::BigInt::GMP", (void*)TEMP_2)); */
/* y -= x */
mpz_sub(*TEMP_1, *TEMP, *TEMP_1);
PUSHs( y );
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions META.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
--- #YAML:1.0
name: Math-BigInt-GMP
version: 1.16
version: 1.17
version_from: lib/Math/BigInt/GMP.pm
license: perl
distribution_type: module
generated_by: Math-BigInt-GMP version 1.16
generated_by: Math-BigInt-GMP version 1.17
installdirs: site
requires:
Math::BigFloat: 1.47
Math::BigInt: 1.73
Math::BigInt: 1.74
XSLoader: 0.02
4 changes: 2 additions & 2 deletions Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ WriteMakefile(
'NAME' => 'Math::BigInt::GMP',
'VERSION_FROM' => 'lib/Math/BigInt/GMP.pm', # finds $VERSION
'PREREQ_PM' => {
Math::BigInt => 1.73,
Math::BigFloat => 1.47,
Math::BigInt => 1.74,
XSLoader => 0.02,
},
'LIBS' => ['-lgmp'], # e.g., '-lm'
'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
Expand Down
29 changes: 19 additions & 10 deletions NEW
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@

Changes between the last and this version:

v1.16:
* fixed a leak in _div() and simplified it (Thanx Tassilo v. Parseval)
* moved the _div() code to XS to make it a bit faster
* put leak.pl and leaktest into MANIFEST for later checking
v1.17:
* 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))

#############################################################################

v1.15:
221 / 444: 5 wallclock secs ( 5.20 usr + 0.01 sys = 5.21 CPU) @ 18940/s (n=98679)
444 / 221: 6 wallclock secs ( 5.20 usr + 0.01 sys = 5.21 CPU) @ 19108/s (n=99555)

v1.16:
221 / 444: 6 wallclock secs ( 5.24 usr + 0.01 sys = 5.25 CPU) @ 20957/s (n=110026)
444 / 221: 5 wallclock secs ( 5.28 usr + 0.00 sys = 5.28 CPU) @ 21231/s (n=112102)

Benchmark: running zeros(1.0x1000), zeros(123), zeros(1x1000) for at least 5 CPU seconds...
zeros(1.0x1000): 5s (5.02 usr + 0.15 sys = 5.17 CPU) @ 14179/s (n=73309)
zeros(123): 5s (5.19 usr + 0.11 sys = 5.30 CPU) @ 253584/s (n=1344000)
zeros(1x1000): 5s (5.06 usr + 0.17 sys = 5.23 CPU) @ 14106/s (n=73777)


v1.17:
Benchmark: running zeros(1.0x1000), zeros(123), zeros(1x1000) for at least 5 CPU seconds...
zeros(1.0x1000): 5s (5.06 usr + 0.15 sys = 5.21 CPU) @ 14160/s (n=73777)
zeros(123): 5s (5.27 usr + 0.01 sys = 5.28 CPU) @ 299044/s (n=1578957)
zeros(1x1000): 5s (5.21 usr + 0.01 sys = 5.22 CPU) @ 302482/s (n=1578957)

42 changes: 21 additions & 21 deletions SIGNATURE
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
This file contains message digests of all files listed in MANIFEST,
signed via the Module::Signature module, version 0.41.
signed via the Module::Signature module, version 0.42.

To verify the content in this distribution, first make sure you have
Module::Signature installed, then type:

% cpansign -v

It would check each file's integrity, as well as the signature's
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-----

SHA1 70d6187d0152848c922dc4360fa6dd3a3dc35c62 BUGS
SHA1 3743ce85e7e98c882bd05ec9eebcfb31ff453815 CHANGES
SHA1 10ba246d1dbff89a3905428d6f76f42aef36579a CHANGES
SHA1 dda5ca4f413031e9efcaa1600461d5e2adaa3a40 CREDITS
SHA1 636480140c61a18f193b0178dc9809c295d9456a GMP.xs
SHA1 c6b4374d7e911bd399534af9fa5ceb8c90dc6485 GMP.xs
SHA1 1c219a49ee07891ca39de3f89ce4bbe02549af82 INSTALL
SHA1 d6a6c30ee6d9ba6b9afab8bbf6a25e1b23c744e0 LICENSE
SHA1 6cd50151e6eab24927bce91ec062e6d71724ce63 MANIFEST
SHA1 9c0c8cf77b1ce503893fba602c9ea48cb1d996b9 META.yml
SHA1 185af48c59491c5e3351c6d9950c3565de74005a Makefile.PL
SHA1 704f02fad759cc0d99558352f5a7cfb7d8c11b1e NEW
SHA1 8b0a5a75c4530c61658e4af1cd76420270023e19 META.yml
SHA1 83262bb7cc34f4016ed89005e3b0d93438963f31 Makefile.PL
SHA1 2be04f1ccd8a14a7e00e99ce661a47e579f9f02f NEW
SHA1 e9de29b6e5e9a5e446231b5b12b644f6ed2caafc README
SHA1 e4fd0b099ed6ef332c72cbf85719a7cf1bd2dc6a TODO
SHA1 200ade10e14449652ac59d0c8a9569cf29645cbd TODO
SHA1 fd48d0d8750eb949e485d8136b5b424fe73e9775 build/README
SHA1 c93694211f8ba09c49ae69b5f3fd4d957bd26f62 build/leak.pl
SHA1 7bcc4113830721ad6e37a1ea79df94a6987c836d build/leak.pl
SHA1 ac25bda8a6eb9058a9e42a8943c3e11b9fed88dc build/leaktest
SHA1 bed207cfb72446fcb746c8d438538b6801a181fd lib/Math/BigInt/GMP.pm
SHA1 7704eb924e8a297edafa95c5075df502bbc2f14a t/bigfltpm.inc
SHA1 3287807111be40445e3f8ed5cb1f738996e2b18d t/bigfltpm.t
SHA1 b0f41f0025528cfea909c9a212c2e377ee3d9243 t/bigintg.t
SHA1 43b2f324aa16df6865272c192bcab9f25bf7008e t/bigintpm.inc
SHA1 103f5b902922eba6550271837d8d64d6c40d73d7 lib/Math/BigInt/GMP.pm
SHA1 57a416650fede5f54aa295e5cd133022a0b9efdd t/bigfltpm.inc
SHA1 ba0b4085ef17b06a733d7ee26cb5b54ecf4c6094 t/bigfltpm.t
SHA1 d552991e5df86d3f04b6928c97efe2653fc776d2 t/bigintg.t
SHA1 aaaea1e9f34d1dfe090911863e5289f85f83ed46 t/bigintpm.inc
SHA1 6dfbf7bc6601b23073204e9c104d3b68213c93ab t/bigintpm.t
SHA1 f7aad87c0a30330d474f4fb45f6d1953d6701d2f typemap
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iQEVAwUBQboC9XcLPEOTuEwVAQFPLQf+Olfms17l/g4dhwcRpRLtaAm525xWEtiV
ARQnCf/xIYfhmDR4deih71aDX6PXjRjihukU+OtPIMdE6MyHUUbzvNqGa0waPIor
O+eOqZlZnyjJLvFGKZXJJtFF39M0ZSzmrMh9wuYvRzQhdKNXgqCju20Ni9puw6IA
tD+V7Y0I5FkXJOCewy8NECoXnQjlcSAiWHZRsByDkJSLA6pBtoQUXuzN73D8I1P/
JEOuQTQ0ZlF+kFs9wSShOoYYc16OS/EGcBWHw8F8jdzENErmUZ/RP7E9E4fMewey
0MnJ9V2gRHu5Qe8oaoQs8UcaqrWOE5QG/bhW7rcXCVRL4RxNXv0iTw==
=GgRM
iQEVAwUBQdbBZXcLPEOTuEwVAQGaAwf8DE9+TD70VMuSB8qPkutFHacs2Z1ztUGf
pqNMNtKi/Y6W7gY0zyQbp7nqwX8oR2Dcx5ULi1UuIM3MzIaDlB/se0ThEqsd+No4
a9pjBxqnQ3zDisFCqtsEWsEmvBYu7JUH2y4ZSe46p2qfm/UYGFBXzjm9PXXpVQyn
JU/0GxsQrhfZBnEIKT4KbPzDKp1oPLw0gf41+Zmh6clix4hp5i0zUNycwSX9nUWV
KNVpO41KgMDjZURTRazFbZgz+DgIymvdgp8yCTNv5DGLTfhNpS0c0hj6EyVmXnTQ
iiX+YLRUkwr2yLfKwLN4p2kk4KO7rL9oA9M9AHS/y8/cqvidUiXuCQ==
=bjyF
-----END PGP SIGNATURE-----
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

* _lsft() and _rsft() could probably be a bit more optimized
* move _log_int() to XS
* move sub() and div() completely to XS ?
* _digit() and _len() could be more optimized
* _zeros() could be more optimized (divide by 1e5, check for == 0?)
* replace all malloc() with New() and all free() with Savefree()?
Expand Down
3 changes: 2 additions & 1 deletion build/leak.pl
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@
[ 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..10) { &{$do->[0]}; }
for (1..13) { &{$do->[0]}; }
print "$do->[1] leaked ", Devel::Leak::CheckSV($handle) - $count, " things\n";
}

Expand Down
10 changes: 4 additions & 6 deletions lib/Math/BigInt/GMP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ use strict;
use 5.005;
# use warnings; # dont use warnings for older Perls

require Exporter;
require DynaLoader;
use vars qw/$VERSION/;

use vars qw/@ISA $VERSION/;
@ISA = qw(Exporter DynaLoader);
$VERSION = '1.16';
$VERSION = '1.17';

bootstrap Math::BigInt::GMP $VERSION;
use XSLoader;
XSLoader::load "Math::BigInt::GMP", $VERSION;

sub import { } # catch and throw away
sub api_version() { 1; } # we are compatible with MBI v1.70 and up
Expand Down
63 changes: 61 additions & 2 deletions t/bigfltpm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ok ($class->config()->{lib},$CL);

use strict;

my $z;

while (<DATA>)
{
chomp;
Expand Down Expand Up @@ -87,7 +89,27 @@ while (<DATA>)
else
{
$try .= "\$y = $class->new(\"$args[1]\");";
if ($f eq "fcmp") {

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 <=> $y;';
} elsif ($f eq "facmp") {
$try .= '$x->facmp($y);';
Expand Down Expand Up @@ -115,6 +137,7 @@ while (<DATA>)
}
# print "# Trying: '$try'\n";
$ans1 = eval $try;
print "# Error: $@\n" if $@;
if ($ans =~ m|^/(.*)$|)
{
my $pat = $1;
Expand Down Expand Up @@ -337,6 +360,42 @@ sub ok_undef
}

__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;
&flog
0::NaN
Expand Down Expand Up @@ -1479,7 +1538,7 @@ abc:0
1200:1
-1200:1
&is_positive
0:1
0:0
1:1
-1:0
-123:0
Expand Down
2 changes: 1 addition & 1 deletion t/bigfltpm.t
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ BEGIN
unshift @INC, '../lib'; # for running manually
unshift @INC, '../blib/arch';
chdir 't' if -d 't';
plan tests => 1924;
plan tests => 1992;
}

use Math::BigInt lib => 'GMP';
Expand Down
Loading

0 comments on commit 8d2e972

Please sign in to comment.