From: Tels Date: Sun, 27 May 2007 14:43:15 +0000 (+0000) Subject: Math::BigInt::FastCalc v0.15 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5ed38b1ae4fd036cc1b5bf10f27b7489693fb652;p=p5sagit%2Fp5-mst-13.2.git Math::BigInt::FastCalc v0.15 Message-Id: <200705271443.16138@bloodgate.com> p4raw-id: //depot/perl@31284 --- diff --git a/ext/Math/BigInt/FastCalc/FastCalc.pm b/ext/Math/BigInt/FastCalc/FastCalc.pm index 3797def..af464f1 100644 --- a/ext/Math/BigInt/FastCalc/FastCalc.pm +++ b/ext/Math/BigInt/FastCalc/FastCalc.pm @@ -11,7 +11,7 @@ use vars qw/@ISA $VERSION $BASE $BASE_LEN/; @ISA = qw(DynaLoader); -$VERSION = '0.14'; +$VERSION = '0.15'; bootstrap Math::BigInt::FastCalc $VERSION; @@ -26,12 +26,12 @@ BEGIN # use Calc to override the methods that we do not provide in XS for my $method (qw/ - new str + str add sub mul div rsft lsft mod modpow modinv gcd - pow root sqrt log_int fac + pow root sqrt log_int fac nok digit check from_hex from_bin from_oct as_hex as_bin as_oct zeros length base_len diff --git a/ext/Math/BigInt/FastCalc/FastCalc.xs b/ext/Math/BigInt/FastCalc/FastCalc.xs index b00ed05..cd2ca4b 100644 --- a/ext/Math/BigInt/FastCalc/FastCalc.xs +++ b/ext/Math/BigInt/FastCalc/FastCalc.xs @@ -20,6 +20,8 @@ MODULE = Math::BigInt::FastCalc PACKAGE = Math::BigInt::FastCalc # * added _is_two(), _is_ten(), _ten() # 2007-04-02 0.08 Tels # * plug leaks by creating mortals + # 2007-05-27 0.09 Tels + # * add _new() #define RETURN_MORTAL_INT(value) \ ST(0) = sv_2mortal(newSViv(value)); \ @@ -43,6 +45,58 @@ _set_XS_BASE(BASE, BASE_LEN) XS_BASE_LEN = SvIV(BASE_LEN); ############################################################################## +# _new + +AV * +_new(class, x) + SV* x + INIT: + STRLEN len; + char* cur; + int part_len; + + CODE: + /* create the array */ + RETVAL = newAV(); + sv_2mortal((SV*)RETVAL); + /* cur = SvPV(x, len); printf ("input '%s'\n", cur); */ + if (SvIOK(x) && SvIV(x) < XS_BASE) + { + /* shortcut for integer arguments */ + av_push (RETVAL, newSViv( SvIV(x) )); + } + else + { + /* split the input (as string) into XS_BASE_LEN long parts */ + /* in perl: + [ reverse(unpack("a" . ($il % $BASE_LEN+1) + . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ]; + */ + cur = SvPV(x, len); /* convert to string & store length */ + cur += len; /* doing "cur = SvEND(x)" does not work! */ + # process the string from the back + while (len > 0) + { + /* use either BASE_LEN or the amount of remaining digits */ + part_len = XS_BASE_LEN; + if (part_len > len) + { + part_len = len; + } + /* processed so many digits */ + cur -= part_len; + len -= part_len; + /* printf ("part '%s' (part_len: %i, len: %i, BASE_LEN: %i)\n", cur, part_len, len, XS_BASE_LEN); */ + if (part_len > 0) + { + av_push (RETVAL, newSVpvn(cur, part_len) ); + } + } + } + OUTPUT: + RETVAL + +############################################################################## # _copy void diff --git a/ext/Math/BigInt/FastCalc/Makefile.PL b/ext/Math/BigInt/FastCalc/Makefile.PL index b63213b..6307098 100644 --- a/ext/Math/BigInt/FastCalc/Makefile.PL +++ b/ext/Math/BigInt/FastCalc/Makefile.PL @@ -6,7 +6,7 @@ WriteMakefile( 'NAME' => 'Math::BigInt::FastCalc', 'VERSION_FROM' => 'FastCalc.pm', 'PREREQ_PM' => { - 'Math::BigInt' => 1.83, + 'Math::BigInt' => 1.86, }, INSTALLDIRS => 'perl', PREREQ_FATAL => 1, diff --git a/ext/Math/BigInt/FastCalc/t/leak.t b/ext/Math/BigInt/FastCalc/t/leak.t index b9cc596..7de331a 100644 --- a/ext/Math/BigInt/FastCalc/t/leak.t +++ b/ext/Math/BigInt/FastCalc/t/leak.t @@ -13,9 +13,11 @@ BEGIN $| = 1; chdir 't' if -d 't'; unshift @INC, ('../lib', '../blib/arch'); # for running manually - plan tests => 20; + plan tests => 22; } +use Math::BigInt::FastCalc; + ############################################################################# package Math::BigInt::FastCalc::LeakCheck; use base qw(Math::BigInt::FastCalc); @@ -53,6 +55,9 @@ my $num_2 = Math::BigInt::FastCalc->_two(); my $num_long = Math::BigInt::FastCalc->_new("1234567890"); my $num_long_2 = Math::BigInt::FastCalc->_new("12345678900987654321"); +is (Math::BigInt::FastCalc->_str($num_long), "1234567890"); +is (Math::BigInt::FastCalc->_str($num_long_2), "12345678900987654321"); + # to hit all possible code branches _test_acmp($num, $num); _test_acmp($num_10, $num_10);