1 package Math::BigInt::Calc;
5 # use warnings; # dont use warnings for older Perls
8 use vars qw/@ISA $VERSION/;
13 # Package to store unsigned big integers in decimal and do math with them
15 # Internally the numbers are stored in an array with at least 1 element, no
16 # leading zero parts (except the first) and in base 100000
19 # - fully remove funky $# stuff (maybe)
21 # USE_MUL: due to problems on certain os (os390, posix-bc) "* 1e-5" is used
22 # instead of "/ 1e5" at some places, (marked with USE_MUL). Other platforms
23 # BS2000, some Crays need USE_DIV instead.
24 # The BEGIN block is used to determine which of the two variants gives the
27 ##############################################################################
28 # global constants, flags and accessory
30 # constants for easier life
32 my ($BASE,$RBASE,$BASE_LEN,$MAX_VAL);
36 # set/get the BASE_LEN and assorted other, connected values
37 # used only be the testsuite, set is used only by the BEGIN block below
41 $b = 8 if $b > 8; # cap, for VMS, OS/390 and other 64 bit
43 $BASE = int("1e".$BASE_LEN);
44 $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL
46 # print "BASE_LEN: $BASE_LEN MAX_VAL: $MAX_VAL\n";
47 # print "int: ",int($BASE * $RBASE),"\n";
48 if (int($BASE * $RBASE) == 0) # should be 1
51 *{_mul} = \&_mul_use_mul;
52 *{_div} = \&_div_use_mul;
57 *{_mul} = \&_mul_use_div;
58 *{_div} = \&_div_use_div;
66 # from Daniel Pfeiffer: determine largest group of digits that is precisely
67 # multipliable with itself plus carry
68 # Test now changed to expect the proper pattern, not a result off by 1 or 2
69 my ($e, $num) = 3; # lowest value we will use is 3+1-1 = 3
72 $num = ('9' x ++$e) + 0;
75 } while ("$num" =~ /9{$e}0{$e}/); # must be a certain pattern
76 # last test failed, so retract one step:
80 ##############################################################################
81 # create objects from various representations
85 # (string) return ref to num_array
86 # Convert a number from string format to internal base 100000 format.
87 # Assumes normalized value as input.
89 # print "_new $d $$d\n";
90 my $il = CORE::length($$d)-1;
91 # these leaves '00000' instead of int 0 and will be corrected after any op
92 return [ reverse(unpack("a" . ($il % $BASE_LEN+1)
93 . ("a$BASE_LEN" x ($il / $BASE_LEN)), $$d)) ];
113 # catch and throw away
116 ##############################################################################
117 # convert back to string and number
121 # (ref to BINT) return num_str
122 # Convert number from internal base 100000 format to string format.
123 # internal format is always normalized (no leading zeros, "-0" => "+0")
126 my $l = scalar @$ar; # number of parts
127 return $nan if $l < 1; # should not happen
128 # handle first one different to strip leading zeros from it (there are no
129 # leading zero parts in internal representation)
130 $l --; $ret .= $ar->[$l]; $l--;
131 # Interestingly, the pre-padd method uses more time
132 # the old grep variant takes longer (14 to 10 sec)
133 my $z = '0' x ($BASE_LEN-1);
136 $ret .= substr($z.$ar->[$l],-$BASE_LEN); # fastest way I could think of
144 # Make a number (scalar int/float) from a BigInt object
146 return $x->[0] if scalar @$x == 1; # below $BASE
151 $num += $fac*$_; $fac *= $BASE;
156 ##############################################################################
161 # (ref to int_num_array, ref to int_num_array)
162 # routine to add two base 1eX numbers
163 # stolen from Knuth Vol 2 Algorithm A pg 231
164 # there are separate routines to add and sub as per Knuth pg 233
165 # This routine clobbers up array x, but not y.
169 # for each in Y, add Y to X and carry. If after that, something is left in
170 # X, foreach in X add carry to X and then return X, carry
171 # Trades one "$j++" for having to shift arrays, $j could be made integer
172 # but this would impose a limit to number-length of 2**32.
173 my $i; my $car = 0; my $j = 0;
176 $x->[$j] -= $BASE if $car = (($x->[$j] += $i + $car) >= $BASE) ? 1 : 0;
181 $x->[$j] -= $BASE if $car = (($x->[$j] += $car) >= $BASE) ? 1 : 0; $j++;
188 # (ref to int_num_array, ref to int_num_array)
189 # routine to add 1 to a base 1eX numbers
190 # This routine clobbers up array x, but not y.
195 return $x if (($i += 1) < $BASE); # early out
198 if ($x->[-1] == 0) # last overflowed
207 # (ref to int_num_array, ref to int_num_array)
208 # routine to add 1 to a base 1eX numbers
209 # This routine clobbers up array x, but not y.
214 last if (($i -= 1) >= 0); # early out
217 pop @$x if $x->[-1] == 0 && @$x > 1; # last overflowed (but leave 0)
223 # (ref to int_num_array, ref to int_num_array)
224 # subtract base 1eX numbers -- stolen from Knuth Vol 2 pg 232, $x > $y
225 # subtract Y from X (X is always greater/equal!) by modifying x in place
226 my ($c,$sx,$sy,$s) = @_;
228 my $car = 0; my $i; my $j = 0;
234 last unless defined $sy->[$j] || $car;
235 #print "x: $i y: $sy->[$j] c: $car\n";
236 $i += $BASE if $car = (($i -= ($sy->[$j] || 0) + $car) < 0); $j++;
237 #print "x: $i y: $sy->[$j-1] c: $car\n";
239 # might leave leading zeros, so fix that
245 #print "case 1 (swap)\n";
248 last unless defined $sy->[$j] || $car;
249 #print "$sy->[$j] $i $car => $sx->[$j]\n";
251 if $car = (($sy->[$j] = $i-($sy->[$j]||0) - $car) < 0);
252 #print "$sy->[$j] $i $car => $sy->[$j]\n";
255 # might leave leading zeros, so fix that
263 # (BINT, BINT) return nothing
264 # multiply two numbers in internal representation
265 # modifies first arg, second need not be different from first
266 my ($c,$xv,$yv) = @_;
268 my @prod = (); my ($prod,$car,$cty,$xi,$yi);
269 # since multiplying $x with $x fails, make copy in this case
270 $yv = [@$xv] if "$xv" eq "$yv"; # same references?
278 # $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
280 # $prod - ($car = int($prod * RBASE)) * $BASE; # see USE_MUL
282 # $prod[$cty] += $car if $car; # need really to check for 0?
286 # looping through this if $xi == 0 is silly - so optimize it away!
287 $xi = (shift @prod || 0), next if $xi == 0;
290 $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
291 ## this is actually a tad slower
292 ## $prod = $prod[$cty]; $prod += ($car + $xi * $yi); # no ||0 here
294 $prod - ($car = int($prod * $RBASE)) * $BASE; # see USE_MUL
296 $prod[$cty] += $car if $car; # need really to check for 0?
301 # normalize (handled last to save check for $y->is_zero()
307 # (BINT, BINT) return nothing
308 # multiply two numbers in internal representation
309 # modifies first arg, second need not be different from first
310 my ($c,$xv,$yv) = @_;
312 my @prod = (); my ($prod,$car,$cty,$xi,$yi);
313 # since multiplying $x with $x fails, make copy in this case
314 $yv = [@$xv] if "$xv" eq "$yv"; # same references?
318 # looping through this if $xi == 0 is silly - so optimize it away!
319 $xi = (shift @prod || 0), next if $xi == 0;
322 $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
324 $prod - ($car = int($prod / $BASE)) * $BASE;
326 $prod[$cty] += $car if $car; # need really to check for 0?
331 # normalize (handled last to save check for $y->is_zero()
337 # ref to array, ref to array, modify first array and return remainder if
339 # no longer handles sign
340 my ($c,$x,$yorg) = @_;
341 my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1);
343 my (@d,$tmp,$q,$u2,$u1,$u0);
345 $car = $bar = $prd = 0;
348 if (($dd = int($BASE/($y->[-1]+1))) != 1)
352 $xi = $xi * $dd + $car;
353 $xi -= ($car = int($xi * $RBASE)) * $BASE; # see USE_MUL
355 push(@$x, $car); $car = 0;
358 $yi = $yi * $dd + $car;
359 $yi -= ($car = int($yi * $RBASE)) * $BASE; # see USE_MUL
366 @q = (); ($v2,$v1) = @$y[-2,-1];
370 ($u2,$u1,$u0) = @$x[-3..-1];
372 #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
374 # $q = (($u0 == $v1) ? 99999 : int(($u0*$BASE+$u1)/$v1));
375 $q = (($u0 == $v1) ? $MAX_VAL : int(($u0*$BASE+$u1)/$v1));
376 --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2);
379 ($car, $bar) = (0,0);
380 for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
382 $prd = $q * $y->[$yi] + $car;
383 $prd -= ($car = int($prd * $RBASE)) * $BASE; # see USE_MUL
384 $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
386 if ($x->[-1] < $car + $bar)
389 for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
392 if ($car = (($x->[$xi] += $y->[$yi] + $car) > $BASE));
396 pop(@$x); unshift(@q, $q);
404 for $xi (reverse @$x)
406 $prd = $car * $BASE + $xi;
407 $car = $prd - ($tmp = int($prd / $dd)) * $dd; # see USE_MUL
427 # ref to array, ref to array, modify first array and return remainder if
429 # no longer handles sign
430 my ($c,$x,$yorg) = @_;
431 my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1);
433 my (@d,$tmp,$q,$u2,$u1,$u0);
435 $car = $bar = $prd = 0;
438 if (($dd = int($BASE/($y->[-1]+1))) != 1)
442 $xi = $xi * $dd + $car;
443 $xi -= ($car = int($xi / $BASE)) * $BASE;
445 push(@$x, $car); $car = 0;
448 $yi = $yi * $dd + $car;
449 $yi -= ($car = int($yi / $BASE)) * $BASE;
456 @q = (); ($v2,$v1) = @$y[-2,-1];
460 ($u2,$u1,$u0) = @$x[-3..-1];
462 #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
464 # $q = (($u0 == $v1) ? 99999 : int(($u0*$BASE+$u1)/$v1));
465 $q = (($u0 == $v1) ? $MAX_VAL : int(($u0*$BASE+$u1)/$v1));
466 --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2);
469 ($car, $bar) = (0,0);
470 for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
472 $prd = $q * $y->[$yi] + $car;
473 $prd -= ($car = int($prd / $BASE)) * $BASE;
474 $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
476 if ($x->[-1] < $car + $bar)
479 for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
482 if ($car = (($x->[$xi] += $y->[$yi] + $car) > $BASE));
486 pop(@$x); unshift(@q, $q);
494 for $xi (reverse @$x)
496 $prd = $car * $BASE + $xi;
497 $car = $prd - ($tmp = int($prd / $dd)) * $dd;
517 # if possible, use mod shortcut
520 # slow way since $y to big
523 my ($xo,$rem) = _div($c,$x,$yo);
527 # both are single element
537 # when BASE % Y == 0 then (B * BASE) % Y == 0
538 # (B * BASE) % $y + A % Y => A % Y
539 # so need to consider only last element: O(1)
544 # else need to go trough all elemens: O(N)
546 my ($xo,$rem) = _div($c,$x,$yo);
549 # my $i = 0; my $r = 1;
553 # print "$_ $r $b $y\n";
554 # print "\$_ % \$y = ",$_ % $y,"\n";
555 # print "\$_ % \$y * \$b = ",($_ % $y) * $b,"\n";
556 # $r += ($_ % $y) * $b;
557 # print "$r $b $y =>";
558 # $r %= $y if $r > $y;
567 ##############################################################################
572 my ($c,$x,$y,$n) = @_;
576 return; # we cant do this here, due to now _pow, so signal failure
580 # shortcut (faster) for shifting by 10)
581 # multiples of $BASE_LEN
582 my $dst = 0; # destination
583 my $src = _num($c,$y); # as normal int
584 my $rem = $src % $BASE_LEN; # remainder to shift
585 $src = int($src / $BASE_LEN); # source
588 splice (@$x,0,$src); # even faster, 38.4 => 39.3
592 my $len = scalar @$x - $src; # elems to go
593 my $vd; my $z = '0'x $BASE_LEN;
594 $x->[scalar @$x] = 0; # avoid || 0 test inside loop
598 #print "$dst $src '$vd' ";
599 $vd = substr($vd,-$BASE_LEN,$BASE_LEN-$rem);
602 $vd = substr($z.$x->[$src],-$rem,$rem) . $vd;
605 $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN;
606 $x->[$dst] = int($vd);
609 splice (@$x,$dst) if $dst > 0; # kill left-over array elems
610 pop @$x if $x->[-1] == 0; # kill last element if 0
618 my ($c,$x,$y,$n) = @_;
622 return; # we cant do this here, due to now _pow, so signal failure
626 # shortcut (faster) for shifting by 10) since we are in base 10eX
627 # multiples of $BASE_LEN:
628 my $src = scalar @$x; # source
629 my $len = _num($c,$y); # shift-len as normal int
630 my $rem = $len % $BASE_LEN; # remainder to shift
631 my $dst = $src + int($len/$BASE_LEN); # destination
632 my $vd; # further speedup
633 #print "src $src:",$x->[$src]||0," dst $dst:",$v->[$dst]||0," rem $rem\n";
634 $x->[$src] = 0; # avoid first ||0 for speed
635 my $z = '0' x $BASE_LEN;
638 $vd = $x->[$src]; $vd = $z.$vd;
639 #print "s $src d $dst '$vd' ";
640 $vd = substr($vd,-$BASE_LEN+$rem,$BASE_LEN-$rem);
642 $vd .= $src > 0 ? substr($z.$x->[$src-1],-$BASE_LEN,$rem) : '0' x $rem;
644 $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN;
646 $x->[$dst] = int($vd);
649 # set lowest parts to 0
650 while ($dst >= 0) { $x->[$dst--] = 0; }
651 # fix spurios last zero element
652 splice @$x,-1 if $x->[-1] == 0;
653 #print "elems: "; my $i = 0;
654 #foreach (reverse @$v) { print "$i $_ "; $i++; } print "\n";
659 ##############################################################################
664 # internal absolute post-normalized compare (ignore signs)
665 # ref to array, ref to array, return <0, 0, >0
666 # arrays must have at least one entry; this is not checked for
668 my ($c,$cx, $cy) = @_;
672 # calculate length based on digits, not parts
673 $x = _len('',$cx); $y = _len('',$cy);
674 # print "length: ",($x-$y),"\n";
675 my $lxy = $x - $y; # if different in length
676 return -1 if $lxy < 0;
677 return 1 if $lxy > 0;
678 #print "full compare\n";
680 # first way takes 5.49 sec instead of 4.87, but has the early out advantage
681 # so grep is slightly faster, but more inflexible. hm. $_ instead of $k
682 # yields 5.6 instead of 5.5 sec huh?
683 # manual way (abort if unequal, good for early ne)
684 my $j = scalar @$cx - 1;
687 # print "$cx->[$j] $cy->[$j] $a",$cx->[$j]-$cy->[$j],"\n";
688 last if ($a = $cx->[$j] - $cy->[$j]); $j--;
693 # while it early aborts, it is even slower than the manual variant
694 #grep { return $a if ($a = $_ - $cy->[$i++]); } @$cx;
695 # grep way, go trough all (bad for early ne)
696 #grep { $a = $_ - $cy->[$i++]; } @$cx;
702 # compute number of digits in bigint, minus the sign
703 # int() because add/sub sometimes leaves strings (like '00005') instead of
704 # int ('5') in this place, thus causing length() to report wrong length
707 return (@$cx-1)*$BASE_LEN+length(int($cx->[-1]));
712 # return the nth digit, negative values count backward
713 # zero is rightmost, so _digit(123,0) will give 3
716 my $len = _len('',$x);
718 $n = $len+$n if $n < 0; # -1 last, -2 second-to-last
719 $n = abs($n); # if negative was too big
720 $len--; $n = $len if $n > $len; # n to big?
722 my $elem = int($n / $BASE_LEN); # which array element
723 my $digit = $n % $BASE_LEN; # which digit in this element
724 $elem = '0000'.@$x[$elem]; # get element padded with 0's
725 return substr($elem,-$digit-1,1);
730 # return amount of trailing zeros in decimal
731 # check each array elem in _m for having 0 at end as long as elem == 0
732 # Upon finding a elem != 0, stop
734 my $zeros = 0; my $elem;
739 $elem = "$e"; # preserve x
740 $elem =~ s/.*?(0*$)/$1/; # strip anything not zero
741 $zeros *= $BASE_LEN; # elems * 5
742 $zeros += CORE::length($elem); # count trailing zeros
745 $zeros ++; # real else branch: 50% slower!
750 ##############################################################################
755 # return true if arg (BINT or num_str) is zero (array '+', '0')
757 return (((scalar @$x == 1) && ($x->[0] == 0))) <=> 0;
762 # return true if arg (BINT or num_str) is even
764 return (!($x->[0] & 1)) <=> 0;
769 # return true if arg (BINT or num_str) is even
771 return (($x->[0] & 1)) <=> 0;
776 # return true if arg (BINT or num_str) is one (array '+', '1')
778 return (scalar @$x == 1) && ($x->[0] == 1) <=> 0;
783 # internal normalization function that strips leading zeros from the array
787 my $cnt = scalar @$s; # get count of parts
789 #print "strip: cnt $cnt i $i\n";
790 # '0', '3', '4', '0', '0',
795 # => fcnt = cnt - i (5-2 => 3, cnt => 5-1 = 4, throw away from 4th pos)
796 # >= 1: skip first part (this can be zero)
797 while ($i > 0) { last if $s->[$i] != 0; $i--; }
798 $i++; splice @$s,$i if ($i < $cnt); # $i cant be 0
802 ###############################################################################
803 # check routine to test internal state of corruptions
807 # used by the test suite
810 return "$x is not a reference" if !ref($x);
812 # are all parts are valid?
813 my $i = 0; my $j = scalar @$x; my ($e,$try);
816 $e = $x->[$i]; $e = 'undef' unless defined $e;
817 $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e)";
818 last if $e !~ /^[+]?[0-9]+$/;
819 $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e) (stringify)";
820 last if "$e" !~ /^[+]?[0-9]+$/;
821 $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e) (cat-stringify)";
822 last if '' . "$e" !~ /^[+]?[0-9]+$/;
823 $try = ' < 0 || >= $BASE; '."($x, $e)";
824 last if $e <0 || $e >= $BASE;
825 # this test is disabled, since new/bnorm and certain ops (like early out
826 # in add/sub) are allowed/expected to leave '00000' in some elements
827 #$try = '=~ /^00+/; '."($x, $e)";
828 #last if $e =~ /^00+/;
831 return "Illegal part '$e' at pos $i (tested: $try)" if $i < $j;
840 Math::BigInt::Calc - Pure Perl module to support Math::BigInt
844 Provides support for big integer calculations. Not intended to be used by other
845 modules (except Math::BigInt::Cached). Other modules which sport the same
846 functions can also be used to support Math::Bigint, like Math::BigInt::Pari.
850 In order to allow for multiple big integer libraries, Math::BigInt
851 was rewritten to use library modules for core math routines. Any
852 module which follows the same API as this can be used instead by
853 using the following call:
855 use Math::BigInt lib => 'libname';
859 The following functions MUST be defined in order to support
860 the use by Math::BigInt:
862 _new(string) return ref to new object from ref to decimal string
863 _zero() return a new object with value 0
864 _one() return a new object with value 1
866 _str(obj) return ref to a string representing the object
867 _num(obj) returns a Perl integer/floating point number
868 NOTE: because of Perl numeric notation defaults,
869 the _num'ified obj may lose accuracy due to
870 machine-dependend floating point size limitations
872 _add(obj,obj) Simple addition of two objects
873 _mul(obj,obj) Multiplication of two objects
874 _div(obj,obj) Division of the 1st object by the 2nd
875 In list context, returns (result,remainder).
876 NOTE: this is integer math, so no
877 fractional part will be returned.
878 _sub(obj,obj) Simple subtraction of 1 object from another
879 a third, optional parameter indicates that the params
880 are swapped. In this case, the first param needs to
881 be preserved, while you can destroy the second.
882 sub (x,y,1) => return x - y and keep x intact!
883 _dec(obj) decrement object by one (input is garant. to be > 0)
884 _inc(obj) increment object by one
887 _acmp(obj,obj) <=> operator for objects (return -1, 0 or 1)
889 _len(obj) returns count of the decimal digits of the object
890 _digit(obj,n) returns the n'th decimal digit of object
892 _is_one(obj) return true if argument is +1
893 _is_zero(obj) return true if argument is 0
894 _is_even(obj) return true if argument is even (0,2,4,6..)
895 _is_odd(obj) return true if argument is odd (1,3,5,7..)
897 _copy return a ref to a true copy of the object
899 _check(obj) check whether internal representation is still intact
900 return 0 for ok, otherwise error message as string
902 The following functions are optional, and can be defined if the underlying lib
903 has a fast way to do them. If undefined, Math::BigInt will use a pure, but
904 slow, Perl way as fallback to emulate these:
906 _from_hex(str) return ref to new object from ref to hexadecimal string
907 _from_bin(str) return ref to new object from ref to binary string
909 _as_hex(str) return ref to scalar string containing the value as
910 unsigned hex string, with the '0x' prepended.
911 Leading zeros must be stripped.
912 _as_bin(str) Like as_hex, only as binary string containing only
913 zeros and ones. Leading zeros must be stripped and a
914 '0b' must be prepended.
916 _rsft(obj,N,B) shift object in base B by N 'digits' right
917 For unsupported bases B, return undef to signal failure
918 _lsft(obj,N,B) shift object in base B by N 'digits' left
919 For unsupported bases B, return undef to signal failure
921 _xor(obj1,obj2) XOR (bit-wise) object 1 with object 2
922 Note: XOR, AND and OR pad with zeros if size mismatches
923 _and(obj1,obj2) AND (bit-wise) object 1 with object 2
924 _or(obj1,obj2) OR (bit-wise) object 1 with object 2
926 _mod(obj,obj) Return remainder of div of the 1st by the 2nd object
927 _sqrt(obj) return the square root of object
928 _pow(obj,obj) return object 1 to the power of object 2
929 _gcd(obj,obj) return Greatest Common Divisor of two objects
931 _zeros(obj) return number of trailing decimal zeros
933 Input strings come in as unsigned but with prefix (i.e. as '123', '0xabc'
936 Testing of input parameter validity is done by the caller, so you need not
937 worry about underflow (f.i. in C<_sub()>, C<_dec()>) nor about division by
938 zero or similar cases.
940 The first parameter can be modified, that includes the possibility that you
941 return a reference to a completely different object instead. Although keeping
942 the reference and just changing it's contents is prefered over creating and
943 returning a different reference.
945 Return values are always references to objects or strings. Exceptions are
946 C<_lsft()> and C<_rsft()>, which return undef if they can not shift the
947 argument. This is used to delegate shifting of bases different than 10 back
948 to Math::BigInt, which will use some generic code to calculate the result.
952 If you want to port your own favourite c-lib for big numbers to the
953 Math::BigInt interface, you can take any of the already existing modules as
954 a rough guideline. You should really wrap up the latest BigInt and BigFloat
955 testsuites with your module, and replace in them any of the following:
961 use Math::BigInt lib => 'yourlib';
963 This way you ensure that your library really works 100% within Math::BigInt.
967 This program is free software; you may redistribute it and/or modify it under
968 the same terms as Perl itself.
972 Original math code by Mark Biggar, rewritten by Tels L<http://bloodgate.com/>
974 Seperated from BigInt and shaped API with the help of John Peacock.
978 L<Math::BigInt>, L<Math::BigFloat>, L<Math::BigInt::BitVect>,
979 L<Math::BigInt::GMP>, L<Math::BigInt::Cached> and L<Math::BigInt::Pari>.