/extlib/Math/BigInt/Calc.pm

http://github.com/openmelody/melody · Perl · 2610 lines · 1844 code · 298 blank · 468 comment · 576 complexity · 6c3e35292b0d47638547b913642afc41 MD5 · raw file

  1. package Math::BigInt::Calc;
  2. use 5.006002;
  3. use strict;
  4. # use warnings; # dont use warnings for older Perls
  5. our $VERSION = '0.56';
  6. # Package to store unsigned big integers in decimal and do math with them
  7. # Internally the numbers are stored in an array with at least 1 element, no
  8. # leading zero parts (except the first) and in base 1eX where X is determined
  9. # automatically at loading time to be the maximum possible value
  10. # todo:
  11. # - fully remove funky $# stuff in div() (maybe - that code scares me...)
  12. # USE_MUL: due to problems on certain os (os390, posix-bc) "* 1e-5" is used
  13. # instead of "/ 1e5" at some places, (marked with USE_MUL). Other platforms
  14. # BS2000, some Crays need USE_DIV instead.
  15. # The BEGIN block is used to determine which of the two variants gives the
  16. # correct result.
  17. # Beware of things like:
  18. # $i = $i * $y + $car; $car = int($i / $BASE); $i = $i % $BASE;
  19. # This works on x86, but fails on ARM (SA1100, iPAQ) due to whoknows what
  20. # reasons. So, use this instead (slower, but correct):
  21. # $i = $i * $y + $car; $car = int($i / $BASE); $i -= $BASE * $car;
  22. ##############################################################################
  23. # global constants, flags and accessory
  24. # announce that we are compatible with MBI v1.83 and up
  25. sub api_version () { 2; }
  26. # constants for easier life
  27. my ($BASE,$BASE_LEN,$RBASE,$MAX_VAL);
  28. my ($AND_BITS,$XOR_BITS,$OR_BITS);
  29. my ($AND_MASK,$XOR_MASK,$OR_MASK);
  30. sub _base_len
  31. {
  32. # Set/get the BASE_LEN and assorted other, connected values.
  33. # Used only by the testsuite, the set variant is used only by the BEGIN
  34. # block below:
  35. shift;
  36. my ($b, $int) = @_;
  37. if (defined $b)
  38. {
  39. # avoid redefinitions
  40. undef &_mul;
  41. undef &_div;
  42. if ($] >= 5.008 && $int && $b > 7)
  43. {
  44. $BASE_LEN = $b;
  45. *_mul = \&_mul_use_div_64;
  46. *_div = \&_div_use_div_64;
  47. $BASE = int("1e".$BASE_LEN);
  48. $MAX_VAL = $BASE-1;
  49. return $BASE_LEN unless wantarray;
  50. return ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN, $MAX_VAL,);
  51. }
  52. # find whether we can use mul or div in mul()/div()
  53. $BASE_LEN = $b+1;
  54. my $caught = 0;
  55. while (--$BASE_LEN > 5)
  56. {
  57. $BASE = int("1e".$BASE_LEN);
  58. $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL
  59. $caught = 0;
  60. $caught += 1 if (int($BASE * $RBASE) != 1); # should be 1
  61. $caught += 2 if (int($BASE / $BASE) != 1); # should be 1
  62. last if $caught != 3;
  63. }
  64. $BASE = int("1e".$BASE_LEN);
  65. $RBASE = abs('1e-'.$BASE_LEN); # see USE_MUL
  66. $MAX_VAL = $BASE-1;
  67. # ($caught & 1) != 0 => cannot use MUL
  68. # ($caught & 2) != 0 => cannot use DIV
  69. if ($caught == 2) # 2
  70. {
  71. # must USE_MUL since we cannot use DIV
  72. *_mul = \&_mul_use_mul;
  73. *_div = \&_div_use_mul;
  74. }
  75. else # 0 or 1
  76. {
  77. # can USE_DIV instead
  78. *_mul = \&_mul_use_div;
  79. *_div = \&_div_use_div;
  80. }
  81. }
  82. return $BASE_LEN unless wantarray;
  83. return ($BASE_LEN, $BASE, $AND_BITS, $XOR_BITS, $OR_BITS, $BASE_LEN, $MAX_VAL);
  84. }
  85. sub _new
  86. {
  87. # (ref to string) return ref to num_array
  88. # Convert a number from string format (without sign) to internal base
  89. # 1ex format. Assumes normalized value as input.
  90. my $il = length($_[1])-1;
  91. # < BASE_LEN due len-1 above
  92. return [ int($_[1]) ] if $il < $BASE_LEN; # shortcut for short numbers
  93. # this leaves '00000' instead of int 0 and will be corrected after any op
  94. [ reverse(unpack("a" . ($il % $BASE_LEN+1)
  95. . ("a$BASE_LEN" x ($il / $BASE_LEN)), $_[1])) ];
  96. }
  97. BEGIN
  98. {
  99. # from Daniel Pfeiffer: determine largest group of digits that is precisely
  100. # multipliable with itself plus carry
  101. # Test now changed to expect the proper pattern, not a result off by 1 or 2
  102. my ($e, $num) = 3; # lowest value we will use is 3+1-1 = 3
  103. do
  104. {
  105. $num = ('9' x ++$e) + 0;
  106. $num *= $num + 1.0;
  107. } while ("$num" =~ /9{$e}0{$e}/); # must be a certain pattern
  108. $e--; # last test failed, so retract one step
  109. # the limits below brush the problems with the test above under the rug:
  110. # the test should be able to find the proper $e automatically
  111. $e = 5 if $^O =~ /^uts/; # UTS get's some special treatment
  112. $e = 5 if $^O =~ /^unicos/; # unicos is also problematic (6 seems to work
  113. # there, but we play safe)
  114. my $int = 0;
  115. if ($e > 7)
  116. {
  117. use integer;
  118. my $e1 = 7;
  119. $num = 7;
  120. do
  121. {
  122. $num = ('9' x ++$e1) + 0;
  123. $num *= $num + 1;
  124. } while ("$num" =~ /9{$e1}0{$e1}/); # must be a certain pattern
  125. $e1--; # last test failed, so retract one step
  126. if ($e1 > 7)
  127. {
  128. $int = 1; $e = $e1;
  129. }
  130. }
  131. __PACKAGE__->_base_len($e,$int); # set and store
  132. use integer;
  133. # find out how many bits _and, _or and _xor can take (old default = 16)
  134. # I don't think anybody has yet 128 bit scalars, so let's play safe.
  135. local $^W = 0; # don't warn about 'nonportable number'
  136. $AND_BITS = 15; $XOR_BITS = 15; $OR_BITS = 15;
  137. # find max bits, we will not go higher than numberofbits that fit into $BASE
  138. # to make _and etc simpler (and faster for smaller, slower for large numbers)
  139. my $max = 16;
  140. while (2 ** $max < $BASE) { $max++; }
  141. {
  142. no integer;
  143. $max = 16 if $] < 5.006; # older Perls might not take >16 too well
  144. }
  145. my ($x,$y,$z);
  146. do {
  147. $AND_BITS++;
  148. $x = CORE::oct('0b' . '1' x $AND_BITS); $y = $x & $x;
  149. $z = (2 ** $AND_BITS) - 1;
  150. } while ($AND_BITS < $max && $x == $z && $y == $x);
  151. $AND_BITS --; # retreat one step
  152. do {
  153. $XOR_BITS++;
  154. $x = CORE::oct('0b' . '1' x $XOR_BITS); $y = $x ^ 0;
  155. $z = (2 ** $XOR_BITS) - 1;
  156. } while ($XOR_BITS < $max && $x == $z && $y == $x);
  157. $XOR_BITS --; # retreat one step
  158. do {
  159. $OR_BITS++;
  160. $x = CORE::oct('0b' . '1' x $OR_BITS); $y = $x | $x;
  161. $z = (2 ** $OR_BITS) - 1;
  162. } while ($OR_BITS < $max && $x == $z && $y == $x);
  163. $OR_BITS --; # retreat one step
  164. $AND_MASK = __PACKAGE__->_new( ( 2 ** $AND_BITS ));
  165. $XOR_MASK = __PACKAGE__->_new( ( 2 ** $XOR_BITS ));
  166. $OR_MASK = __PACKAGE__->_new( ( 2 ** $OR_BITS ));
  167. # We can compute the approximate lenght no faster than the real length:
  168. *_alen = \&_len;
  169. }
  170. ###############################################################################
  171. sub _zero
  172. {
  173. # create a zero
  174. [ 0 ];
  175. }
  176. sub _one
  177. {
  178. # create a one
  179. [ 1 ];
  180. }
  181. sub _two
  182. {
  183. # create a two (used internally for shifting)
  184. [ 2 ];
  185. }
  186. sub _ten
  187. {
  188. # create a 10 (used internally for shifting)
  189. [ 10 ];
  190. }
  191. sub _1ex
  192. {
  193. # create a 1Ex
  194. my $rem = $_[1] % $BASE_LEN; # remainder
  195. my $parts = $_[1] / $BASE_LEN; # parts
  196. # 000000, 000000, 100
  197. [ (0) x $parts, '1' . ('0' x $rem) ];
  198. }
  199. sub _copy
  200. {
  201. # make a true copy
  202. [ @{$_[1]} ];
  203. }
  204. # catch and throw away
  205. sub import { }
  206. ##############################################################################
  207. # convert back to string and number
  208. sub _str
  209. {
  210. # (ref to BINT) return num_str
  211. # Convert number from internal base 100000 format to string format.
  212. # internal format is always normalized (no leading zeros, "-0" => "+0")
  213. my $ar = $_[1];
  214. my $l = scalar @$ar; # number of parts
  215. if ($l < 1) # should not happen
  216. {
  217. require Carp;
  218. Carp::croak("$_[1] has no elements");
  219. }
  220. my $ret = "";
  221. # handle first one different to strip leading zeros from it (there are no
  222. # leading zero parts in internal representation)
  223. $l --; $ret .= int($ar->[$l]); $l--;
  224. # Interestingly, the pre-padd method uses more time
  225. # the old grep variant takes longer (14 vs. 10 sec)
  226. my $z = '0' x ($BASE_LEN-1);
  227. while ($l >= 0)
  228. {
  229. $ret .= substr($z.$ar->[$l],-$BASE_LEN); # fastest way I could think of
  230. $l--;
  231. }
  232. $ret;
  233. }
  234. sub _num
  235. {
  236. # Make a number (scalar int/float) from a BigInt object
  237. my $x = $_[1];
  238. return 0+$x->[0] if scalar @$x == 1; # below $BASE
  239. my $fac = 1;
  240. my $num = 0;
  241. foreach (@$x)
  242. {
  243. $num += $fac*$_; $fac *= $BASE;
  244. }
  245. $num;
  246. }
  247. ##############################################################################
  248. # actual math code
  249. sub _add
  250. {
  251. # (ref to int_num_array, ref to int_num_array)
  252. # routine to add two base 1eX numbers
  253. # stolen from Knuth Vol 2 Algorithm A pg 231
  254. # there are separate routines to add and sub as per Knuth pg 233
  255. # This routine clobbers up array x, but not y.
  256. my ($c,$x,$y) = @_;
  257. return $x if (@$y == 1) && $y->[0] == 0; # $x + 0 => $x
  258. if ((@$x == 1) && $x->[0] == 0) # 0 + $y => $y->copy
  259. {
  260. # twice as slow as $x = [ @$y ], but nec. to retain $x as ref :(
  261. @$x = @$y; return $x;
  262. }
  263. # for each in Y, add Y to X and carry. If after that, something is left in
  264. # X, foreach in X add carry to X and then return X, carry
  265. # Trades one "$j++" for having to shift arrays
  266. my $i; my $car = 0; my $j = 0;
  267. for $i (@$y)
  268. {
  269. $x->[$j] -= $BASE if $car = (($x->[$j] += $i + $car) >= $BASE) ? 1 : 0;
  270. $j++;
  271. }
  272. while ($car != 0)
  273. {
  274. $x->[$j] -= $BASE if $car = (($x->[$j] += $car) >= $BASE) ? 1 : 0; $j++;
  275. }
  276. $x;
  277. }
  278. sub _inc
  279. {
  280. # (ref to int_num_array, ref to int_num_array)
  281. # Add 1 to $x, modify $x in place
  282. my ($c,$x) = @_;
  283. for my $i (@$x)
  284. {
  285. return $x if (($i += 1) < $BASE); # early out
  286. $i = 0; # overflow, next
  287. }
  288. push @$x,1 if (($x->[-1] || 0) == 0); # last overflowed, so extend
  289. $x;
  290. }
  291. sub _dec
  292. {
  293. # (ref to int_num_array, ref to int_num_array)
  294. # Sub 1 from $x, modify $x in place
  295. my ($c,$x) = @_;
  296. my $MAX = $BASE-1; # since MAX_VAL based on BASE
  297. for my $i (@$x)
  298. {
  299. last if (($i -= 1) >= 0); # early out
  300. $i = $MAX; # underflow, next
  301. }
  302. pop @$x if $x->[-1] == 0 && @$x > 1; # last underflowed (but leave 0)
  303. $x;
  304. }
  305. sub _sub
  306. {
  307. # (ref to int_num_array, ref to int_num_array, swap)
  308. # subtract base 1eX numbers -- stolen from Knuth Vol 2 pg 232, $x > $y
  309. # subtract Y from X by modifying x in place
  310. my ($c,$sx,$sy,$s) = @_;
  311. my $car = 0; my $i; my $j = 0;
  312. if (!$s)
  313. {
  314. for $i (@$sx)
  315. {
  316. last unless defined $sy->[$j] || $car;
  317. $i += $BASE if $car = (($i -= ($sy->[$j] || 0) + $car) < 0); $j++;
  318. }
  319. # might leave leading zeros, so fix that
  320. return __strip_zeros($sx);
  321. }
  322. for $i (@$sx)
  323. {
  324. # we can't do an early out if $x is < than $y, since we
  325. # need to copy the high chunks from $y. Found by Bob Mathews.
  326. #last unless defined $sy->[$j] || $car;
  327. $sy->[$j] += $BASE
  328. if $car = (($sy->[$j] = $i-($sy->[$j]||0) - $car) < 0);
  329. $j++;
  330. }
  331. # might leave leading zeros, so fix that
  332. __strip_zeros($sy);
  333. }
  334. sub _mul_use_mul
  335. {
  336. # (ref to int_num_array, ref to int_num_array)
  337. # multiply two numbers in internal representation
  338. # modifies first arg, second need not be different from first
  339. my ($c,$xv,$yv) = @_;
  340. if (@$yv == 1)
  341. {
  342. # shortcut for two very short numbers (improved by Nathan Zook)
  343. # works also if xv and yv are the same reference, and handles also $x == 0
  344. if (@$xv == 1)
  345. {
  346. if (($xv->[0] *= $yv->[0]) >= $BASE)
  347. {
  348. $xv->[0] = $xv->[0] - ($xv->[1] = int($xv->[0] * $RBASE)) * $BASE;
  349. };
  350. return $xv;
  351. }
  352. # $x * 0 => 0
  353. if ($yv->[0] == 0)
  354. {
  355. @$xv = (0);
  356. return $xv;
  357. }
  358. # multiply a large number a by a single element one, so speed up
  359. my $y = $yv->[0]; my $car = 0;
  360. foreach my $i (@$xv)
  361. {
  362. $i = $i * $y + $car; $car = int($i * $RBASE); $i -= $car * $BASE;
  363. }
  364. push @$xv, $car if $car != 0;
  365. return $xv;
  366. }
  367. # shortcut for result $x == 0 => result = 0
  368. return $xv if ( ((@$xv == 1) && ($xv->[0] == 0)) );
  369. # since multiplying $x with $x fails, make copy in this case
  370. $yv = [@$xv] if $xv == $yv; # same references?
  371. my @prod = (); my ($prod,$car,$cty,$xi,$yi);
  372. for $xi (@$xv)
  373. {
  374. $car = 0; $cty = 0;
  375. # slow variant
  376. # for $yi (@$yv)
  377. # {
  378. # $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
  379. # $prod[$cty++] =
  380. # $prod - ($car = int($prod * RBASE)) * $BASE; # see USE_MUL
  381. # }
  382. # $prod[$cty] += $car if $car; # need really to check for 0?
  383. # $xi = shift @prod;
  384. # faster variant
  385. # looping through this if $xi == 0 is silly - so optimize it away!
  386. $xi = (shift @prod || 0), next if $xi == 0;
  387. for $yi (@$yv)
  388. {
  389. $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
  390. ## this is actually a tad slower
  391. ## $prod = $prod[$cty]; $prod += ($car + $xi * $yi); # no ||0 here
  392. $prod[$cty++] =
  393. $prod - ($car = int($prod * $RBASE)) * $BASE; # see USE_MUL
  394. }
  395. $prod[$cty] += $car if $car; # need really to check for 0?
  396. $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
  397. }
  398. push @$xv, @prod;
  399. # can't have leading zeros
  400. # __strip_zeros($xv);
  401. $xv;
  402. }
  403. sub _mul_use_div_64
  404. {
  405. # (ref to int_num_array, ref to int_num_array)
  406. # multiply two numbers in internal representation
  407. # modifies first arg, second need not be different from first
  408. # works for 64 bit integer with "use integer"
  409. my ($c,$xv,$yv) = @_;
  410. use integer;
  411. if (@$yv == 1)
  412. {
  413. # shortcut for two small numbers, also handles $x == 0
  414. if (@$xv == 1)
  415. {
  416. # shortcut for two very short numbers (improved by Nathan Zook)
  417. # works also if xv and yv are the same reference, and handles also $x == 0
  418. if (($xv->[0] *= $yv->[0]) >= $BASE)
  419. {
  420. $xv->[0] =
  421. $xv->[0] - ($xv->[1] = $xv->[0] / $BASE) * $BASE;
  422. };
  423. return $xv;
  424. }
  425. # $x * 0 => 0
  426. if ($yv->[0] == 0)
  427. {
  428. @$xv = (0);
  429. return $xv;
  430. }
  431. # multiply a large number a by a single element one, so speed up
  432. my $y = $yv->[0]; my $car = 0;
  433. foreach my $i (@$xv)
  434. {
  435. #$i = $i * $y + $car; $car = $i / $BASE; $i -= $car * $BASE;
  436. $i = $i * $y + $car; $i -= ($car = $i / $BASE) * $BASE;
  437. }
  438. push @$xv, $car if $car != 0;
  439. return $xv;
  440. }
  441. # shortcut for result $x == 0 => result = 0
  442. return $xv if ( ((@$xv == 1) && ($xv->[0] == 0)) );
  443. # since multiplying $x with $x fails, make copy in this case
  444. $yv = [@$xv] if $xv == $yv; # same references?
  445. my @prod = (); my ($prod,$car,$cty,$xi,$yi);
  446. for $xi (@$xv)
  447. {
  448. $car = 0; $cty = 0;
  449. # looping through this if $xi == 0 is silly - so optimize it away!
  450. $xi = (shift @prod || 0), next if $xi == 0;
  451. for $yi (@$yv)
  452. {
  453. $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
  454. $prod[$cty++] = $prod - ($car = $prod / $BASE) * $BASE;
  455. }
  456. $prod[$cty] += $car if $car; # need really to check for 0?
  457. $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
  458. }
  459. push @$xv, @prod;
  460. $xv;
  461. }
  462. sub _mul_use_div
  463. {
  464. # (ref to int_num_array, ref to int_num_array)
  465. # multiply two numbers in internal representation
  466. # modifies first arg, second need not be different from first
  467. my ($c,$xv,$yv) = @_;
  468. if (@$yv == 1)
  469. {
  470. # shortcut for two small numbers, also handles $x == 0
  471. if (@$xv == 1)
  472. {
  473. # shortcut for two very short numbers (improved by Nathan Zook)
  474. # works also if xv and yv are the same reference, and handles also $x == 0
  475. if (($xv->[0] *= $yv->[0]) >= $BASE)
  476. {
  477. $xv->[0] =
  478. $xv->[0] - ($xv->[1] = int($xv->[0] / $BASE)) * $BASE;
  479. };
  480. return $xv;
  481. }
  482. # $x * 0 => 0
  483. if ($yv->[0] == 0)
  484. {
  485. @$xv = (0);
  486. return $xv;
  487. }
  488. # multiply a large number a by a single element one, so speed up
  489. my $y = $yv->[0]; my $car = 0;
  490. foreach my $i (@$xv)
  491. {
  492. $i = $i * $y + $car; $car = int($i / $BASE); $i -= $car * $BASE;
  493. # This (together with use integer;) does not work on 32-bit Perls
  494. #$i = $i * $y + $car; $i -= ($car = $i / $BASE) * $BASE;
  495. }
  496. push @$xv, $car if $car != 0;
  497. return $xv;
  498. }
  499. # shortcut for result $x == 0 => result = 0
  500. return $xv if ( ((@$xv == 1) && ($xv->[0] == 0)) );
  501. # since multiplying $x with $x fails, make copy in this case
  502. $yv = [@$xv] if $xv == $yv; # same references?
  503. my @prod = (); my ($prod,$car,$cty,$xi,$yi);
  504. for $xi (@$xv)
  505. {
  506. $car = 0; $cty = 0;
  507. # looping through this if $xi == 0 is silly - so optimize it away!
  508. $xi = (shift @prod || 0), next if $xi == 0;
  509. for $yi (@$yv)
  510. {
  511. $prod = $xi * $yi + ($prod[$cty] || 0) + $car;
  512. $prod[$cty++] = $prod - ($car = int($prod / $BASE)) * $BASE;
  513. }
  514. $prod[$cty] += $car if $car; # need really to check for 0?
  515. $xi = shift @prod || 0; # || 0 makes v5.005_3 happy
  516. }
  517. push @$xv, @prod;
  518. # can't have leading zeros
  519. # __strip_zeros($xv);
  520. $xv;
  521. }
  522. sub _div_use_mul
  523. {
  524. # ref to array, ref to array, modify first array and return remainder if
  525. # in list context
  526. # see comments in _div_use_div() for more explanations
  527. my ($c,$x,$yorg) = @_;
  528. # the general div algorithmn here is about O(N*N) and thus quite slow, so
  529. # we first check for some special cases and use shortcuts to handle them.
  530. # This works, because we store the numbers in a chunked format where each
  531. # element contains 5..7 digits (depending on system).
  532. # if both numbers have only one element:
  533. if (@$x == 1 && @$yorg == 1)
  534. {
  535. # shortcut, $yorg and $x are two small numbers
  536. if (wantarray)
  537. {
  538. my $r = [ $x->[0] % $yorg->[0] ];
  539. $x->[0] = int($x->[0] / $yorg->[0]);
  540. return ($x,$r);
  541. }
  542. else
  543. {
  544. $x->[0] = int($x->[0] / $yorg->[0]);
  545. return $x;
  546. }
  547. }
  548. # if x has more than one, but y has only one element:
  549. if (@$yorg == 1)
  550. {
  551. my $rem;
  552. $rem = _mod($c,[ @$x ],$yorg) if wantarray;
  553. # shortcut, $y is < $BASE
  554. my $j = scalar @$x; my $r = 0;
  555. my $y = $yorg->[0]; my $b;
  556. while ($j-- > 0)
  557. {
  558. $b = $r * $BASE + $x->[$j];
  559. $x->[$j] = int($b/$y);
  560. $r = $b % $y;
  561. }
  562. pop @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
  563. return ($x,$rem) if wantarray;
  564. return $x;
  565. }
  566. # now x and y have more than one element
  567. # check whether y has more elements than x, if yet, the result will be 0
  568. if (@$yorg > @$x)
  569. {
  570. my $rem;
  571. $rem = [@$x] if wantarray; # make copy
  572. splice (@$x,1); # keep ref to original array
  573. $x->[0] = 0; # set to 0
  574. return ($x,$rem) if wantarray; # including remainder?
  575. return $x; # only x, which is [0] now
  576. }
  577. # check whether the numbers have the same number of elements, in that case
  578. # the result will fit into one element and can be computed efficiently
  579. if (@$yorg == @$x)
  580. {
  581. my $rem;
  582. # if $yorg has more digits than $x (it's leading element is longer than
  583. # the one from $x), the result will also be 0:
  584. if (length(int($yorg->[-1])) > length(int($x->[-1])))
  585. {
  586. $rem = [@$x] if wantarray; # make copy
  587. splice (@$x,1); # keep ref to org array
  588. $x->[0] = 0; # set to 0
  589. return ($x,$rem) if wantarray; # including remainder?
  590. return $x;
  591. }
  592. # now calculate $x / $yorg
  593. if (length(int($yorg->[-1])) == length(int($x->[-1])))
  594. {
  595. # same length, so make full compare
  596. my $a = 0; my $j = scalar @$x - 1;
  597. # manual way (abort if unequal, good for early ne)
  598. while ($j >= 0)
  599. {
  600. last if ($a = $x->[$j] - $yorg->[$j]); $j--;
  601. }
  602. # $a contains the result of the compare between X and Y
  603. # a < 0: x < y, a == 0: x == y, a > 0: x > y
  604. if ($a <= 0)
  605. {
  606. $rem = [ 0 ]; # a = 0 => x == y => rem 0
  607. $rem = [@$x] if $a != 0; # a < 0 => x < y => rem = x
  608. splice(@$x,1); # keep single element
  609. $x->[0] = 0; # if $a < 0
  610. $x->[0] = 1 if $a == 0; # $x == $y
  611. return ($x,$rem) if wantarray;
  612. return $x;
  613. }
  614. # $x >= $y, so proceed normally
  615. }
  616. }
  617. # all other cases:
  618. my $y = [ @$yorg ]; # always make copy to preserve
  619. my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1,@d,$tmp,$q,$u2,$u1,$u0);
  620. $car = $bar = $prd = 0;
  621. if (($dd = int($BASE/($y->[-1]+1))) != 1)
  622. {
  623. for $xi (@$x)
  624. {
  625. $xi = $xi * $dd + $car;
  626. $xi -= ($car = int($xi * $RBASE)) * $BASE; # see USE_MUL
  627. }
  628. push(@$x, $car); $car = 0;
  629. for $yi (@$y)
  630. {
  631. $yi = $yi * $dd + $car;
  632. $yi -= ($car = int($yi * $RBASE)) * $BASE; # see USE_MUL
  633. }
  634. }
  635. else
  636. {
  637. push(@$x, 0);
  638. }
  639. @q = (); ($v2,$v1) = @$y[-2,-1];
  640. $v2 = 0 unless $v2;
  641. while ($#$x > $#$y)
  642. {
  643. ($u2,$u1,$u0) = @$x[-3..-1];
  644. $u2 = 0 unless $u2;
  645. #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
  646. # if $v1 == 0;
  647. $q = (($u0 == $v1) ? $MAX_VAL : int(($u0*$BASE+$u1)/$v1));
  648. --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2);
  649. if ($q)
  650. {
  651. ($car, $bar) = (0,0);
  652. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  653. {
  654. $prd = $q * $y->[$yi] + $car;
  655. $prd -= ($car = int($prd * $RBASE)) * $BASE; # see USE_MUL
  656. $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
  657. }
  658. if ($x->[-1] < $car + $bar)
  659. {
  660. $car = 0; --$q;
  661. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  662. {
  663. $x->[$xi] -= $BASE
  664. if ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
  665. }
  666. }
  667. }
  668. pop(@$x);
  669. unshift(@q, $q);
  670. }
  671. if (wantarray)
  672. {
  673. @d = ();
  674. if ($dd != 1)
  675. {
  676. $car = 0;
  677. for $xi (reverse @$x)
  678. {
  679. $prd = $car * $BASE + $xi;
  680. $car = $prd - ($tmp = int($prd / $dd)) * $dd; # see USE_MUL
  681. unshift(@d, $tmp);
  682. }
  683. }
  684. else
  685. {
  686. @d = @$x;
  687. }
  688. @$x = @q;
  689. my $d = \@d;
  690. __strip_zeros($x);
  691. __strip_zeros($d);
  692. return ($x,$d);
  693. }
  694. @$x = @q;
  695. __strip_zeros($x);
  696. $x;
  697. }
  698. sub _div_use_div_64
  699. {
  700. # ref to array, ref to array, modify first array and return remainder if
  701. # in list context
  702. # This version works on 64 bit integers
  703. my ($c,$x,$yorg) = @_;
  704. use integer;
  705. # the general div algorithmn here is about O(N*N) and thus quite slow, so
  706. # we first check for some special cases and use shortcuts to handle them.
  707. # This works, because we store the numbers in a chunked format where each
  708. # element contains 5..7 digits (depending on system).
  709. # if both numbers have only one element:
  710. if (@$x == 1 && @$yorg == 1)
  711. {
  712. # shortcut, $yorg and $x are two small numbers
  713. if (wantarray)
  714. {
  715. my $r = [ $x->[0] % $yorg->[0] ];
  716. $x->[0] = int($x->[0] / $yorg->[0]);
  717. return ($x,$r);
  718. }
  719. else
  720. {
  721. $x->[0] = int($x->[0] / $yorg->[0]);
  722. return $x;
  723. }
  724. }
  725. # if x has more than one, but y has only one element:
  726. if (@$yorg == 1)
  727. {
  728. my $rem;
  729. $rem = _mod($c,[ @$x ],$yorg) if wantarray;
  730. # shortcut, $y is < $BASE
  731. my $j = scalar @$x; my $r = 0;
  732. my $y = $yorg->[0]; my $b;
  733. while ($j-- > 0)
  734. {
  735. $b = $r * $BASE + $x->[$j];
  736. $x->[$j] = int($b/$y);
  737. $r = $b % $y;
  738. }
  739. pop @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
  740. return ($x,$rem) if wantarray;
  741. return $x;
  742. }
  743. # now x and y have more than one element
  744. # check whether y has more elements than x, if yet, the result will be 0
  745. if (@$yorg > @$x)
  746. {
  747. my $rem;
  748. $rem = [@$x] if wantarray; # make copy
  749. splice (@$x,1); # keep ref to original array
  750. $x->[0] = 0; # set to 0
  751. return ($x,$rem) if wantarray; # including remainder?
  752. return $x; # only x, which is [0] now
  753. }
  754. # check whether the numbers have the same number of elements, in that case
  755. # the result will fit into one element and can be computed efficiently
  756. if (@$yorg == @$x)
  757. {
  758. my $rem;
  759. # if $yorg has more digits than $x (it's leading element is longer than
  760. # the one from $x), the result will also be 0:
  761. if (length(int($yorg->[-1])) > length(int($x->[-1])))
  762. {
  763. $rem = [@$x] if wantarray; # make copy
  764. splice (@$x,1); # keep ref to org array
  765. $x->[0] = 0; # set to 0
  766. return ($x,$rem) if wantarray; # including remainder?
  767. return $x;
  768. }
  769. # now calculate $x / $yorg
  770. if (length(int($yorg->[-1])) == length(int($x->[-1])))
  771. {
  772. # same length, so make full compare
  773. my $a = 0; my $j = scalar @$x - 1;
  774. # manual way (abort if unequal, good for early ne)
  775. while ($j >= 0)
  776. {
  777. last if ($a = $x->[$j] - $yorg->[$j]); $j--;
  778. }
  779. # $a contains the result of the compare between X and Y
  780. # a < 0: x < y, a == 0: x == y, a > 0: x > y
  781. if ($a <= 0)
  782. {
  783. $rem = [ 0 ]; # a = 0 => x == y => rem 0
  784. $rem = [@$x] if $a != 0; # a < 0 => x < y => rem = x
  785. splice(@$x,1); # keep single element
  786. $x->[0] = 0; # if $a < 0
  787. $x->[0] = 1 if $a == 0; # $x == $y
  788. return ($x,$rem) if wantarray; # including remainder?
  789. return $x;
  790. }
  791. # $x >= $y, so proceed normally
  792. }
  793. }
  794. # all other cases:
  795. my $y = [ @$yorg ]; # always make copy to preserve
  796. my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1,@d,$tmp,$q,$u2,$u1,$u0);
  797. $car = $bar = $prd = 0;
  798. if (($dd = int($BASE/($y->[-1]+1))) != 1)
  799. {
  800. for $xi (@$x)
  801. {
  802. $xi = $xi * $dd + $car;
  803. $xi -= ($car = int($xi / $BASE)) * $BASE;
  804. }
  805. push(@$x, $car); $car = 0;
  806. for $yi (@$y)
  807. {
  808. $yi = $yi * $dd + $car;
  809. $yi -= ($car = int($yi / $BASE)) * $BASE;
  810. }
  811. }
  812. else
  813. {
  814. push(@$x, 0);
  815. }
  816. # @q will accumulate the final result, $q contains the current computed
  817. # part of the final result
  818. @q = (); ($v2,$v1) = @$y[-2,-1];
  819. $v2 = 0 unless $v2;
  820. while ($#$x > $#$y)
  821. {
  822. ($u2,$u1,$u0) = @$x[-3..-1];
  823. $u2 = 0 unless $u2;
  824. #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
  825. # if $v1 == 0;
  826. $q = (($u0 == $v1) ? $MAX_VAL : int(($u0*$BASE+$u1)/$v1));
  827. --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2);
  828. if ($q)
  829. {
  830. ($car, $bar) = (0,0);
  831. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  832. {
  833. $prd = $q * $y->[$yi] + $car;
  834. $prd -= ($car = int($prd / $BASE)) * $BASE;
  835. $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
  836. }
  837. if ($x->[-1] < $car + $bar)
  838. {
  839. $car = 0; --$q;
  840. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  841. {
  842. $x->[$xi] -= $BASE
  843. if ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
  844. }
  845. }
  846. }
  847. pop(@$x); unshift(@q, $q);
  848. }
  849. if (wantarray)
  850. {
  851. @d = ();
  852. if ($dd != 1)
  853. {
  854. $car = 0;
  855. for $xi (reverse @$x)
  856. {
  857. $prd = $car * $BASE + $xi;
  858. $car = $prd - ($tmp = int($prd / $dd)) * $dd;
  859. unshift(@d, $tmp);
  860. }
  861. }
  862. else
  863. {
  864. @d = @$x;
  865. }
  866. @$x = @q;
  867. my $d = \@d;
  868. __strip_zeros($x);
  869. __strip_zeros($d);
  870. return ($x,$d);
  871. }
  872. @$x = @q;
  873. __strip_zeros($x);
  874. $x;
  875. }
  876. sub _div_use_div
  877. {
  878. # ref to array, ref to array, modify first array and return remainder if
  879. # in list context
  880. my ($c,$x,$yorg) = @_;
  881. # the general div algorithmn here is about O(N*N) and thus quite slow, so
  882. # we first check for some special cases and use shortcuts to handle them.
  883. # This works, because we store the numbers in a chunked format where each
  884. # element contains 5..7 digits (depending on system).
  885. # if both numbers have only one element:
  886. if (@$x == 1 && @$yorg == 1)
  887. {
  888. # shortcut, $yorg and $x are two small numbers
  889. if (wantarray)
  890. {
  891. my $r = [ $x->[0] % $yorg->[0] ];
  892. $x->[0] = int($x->[0] / $yorg->[0]);
  893. return ($x,$r);
  894. }
  895. else
  896. {
  897. $x->[0] = int($x->[0] / $yorg->[0]);
  898. return $x;
  899. }
  900. }
  901. # if x has more than one, but y has only one element:
  902. if (@$yorg == 1)
  903. {
  904. my $rem;
  905. $rem = _mod($c,[ @$x ],$yorg) if wantarray;
  906. # shortcut, $y is < $BASE
  907. my $j = scalar @$x; my $r = 0;
  908. my $y = $yorg->[0]; my $b;
  909. while ($j-- > 0)
  910. {
  911. $b = $r * $BASE + $x->[$j];
  912. $x->[$j] = int($b/$y);
  913. $r = $b % $y;
  914. }
  915. pop @$x if @$x > 1 && $x->[-1] == 0; # splice up a leading zero
  916. return ($x,$rem) if wantarray;
  917. return $x;
  918. }
  919. # now x and y have more than one element
  920. # check whether y has more elements than x, if yet, the result will be 0
  921. if (@$yorg > @$x)
  922. {
  923. my $rem;
  924. $rem = [@$x] if wantarray; # make copy
  925. splice (@$x,1); # keep ref to original array
  926. $x->[0] = 0; # set to 0
  927. return ($x,$rem) if wantarray; # including remainder?
  928. return $x; # only x, which is [0] now
  929. }
  930. # check whether the numbers have the same number of elements, in that case
  931. # the result will fit into one element and can be computed efficiently
  932. if (@$yorg == @$x)
  933. {
  934. my $rem;
  935. # if $yorg has more digits than $x (it's leading element is longer than
  936. # the one from $x), the result will also be 0:
  937. if (length(int($yorg->[-1])) > length(int($x->[-1])))
  938. {
  939. $rem = [@$x] if wantarray; # make copy
  940. splice (@$x,1); # keep ref to org array
  941. $x->[0] = 0; # set to 0
  942. return ($x,$rem) if wantarray; # including remainder?
  943. return $x;
  944. }
  945. # now calculate $x / $yorg
  946. if (length(int($yorg->[-1])) == length(int($x->[-1])))
  947. {
  948. # same length, so make full compare
  949. my $a = 0; my $j = scalar @$x - 1;
  950. # manual way (abort if unequal, good for early ne)
  951. while ($j >= 0)
  952. {
  953. last if ($a = $x->[$j] - $yorg->[$j]); $j--;
  954. }
  955. # $a contains the result of the compare between X and Y
  956. # a < 0: x < y, a == 0: x == y, a > 0: x > y
  957. if ($a <= 0)
  958. {
  959. $rem = [ 0 ]; # a = 0 => x == y => rem 0
  960. $rem = [@$x] if $a != 0; # a < 0 => x < y => rem = x
  961. splice(@$x,1); # keep single element
  962. $x->[0] = 0; # if $a < 0
  963. $x->[0] = 1 if $a == 0; # $x == $y
  964. return ($x,$rem) if wantarray; # including remainder?
  965. return $x;
  966. }
  967. # $x >= $y, so proceed normally
  968. }
  969. }
  970. # all other cases:
  971. my $y = [ @$yorg ]; # always make copy to preserve
  972. my ($car,$bar,$prd,$dd,$xi,$yi,@q,$v2,$v1,@d,$tmp,$q,$u2,$u1,$u0);
  973. $car = $bar = $prd = 0;
  974. if (($dd = int($BASE/($y->[-1]+1))) != 1)
  975. {
  976. for $xi (@$x)
  977. {
  978. $xi = $xi * $dd + $car;
  979. $xi -= ($car = int($xi / $BASE)) * $BASE;
  980. }
  981. push(@$x, $car); $car = 0;
  982. for $yi (@$y)
  983. {
  984. $yi = $yi * $dd + $car;
  985. $yi -= ($car = int($yi / $BASE)) * $BASE;
  986. }
  987. }
  988. else
  989. {
  990. push(@$x, 0);
  991. }
  992. # @q will accumulate the final result, $q contains the current computed
  993. # part of the final result
  994. @q = (); ($v2,$v1) = @$y[-2,-1];
  995. $v2 = 0 unless $v2;
  996. while ($#$x > $#$y)
  997. {
  998. ($u2,$u1,$u0) = @$x[-3..-1];
  999. $u2 = 0 unless $u2;
  1000. #warn "oups v1 is 0, u0: $u0 $y->[-2] $y->[-1] l ",scalar @$y,"\n"
  1001. # if $v1 == 0;
  1002. $q = (($u0 == $v1) ? $MAX_VAL : int(($u0*$BASE+$u1)/$v1));
  1003. --$q while ($v2*$q > ($u0*$BASE+$u1-$q*$v1)*$BASE+$u2);
  1004. if ($q)
  1005. {
  1006. ($car, $bar) = (0,0);
  1007. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  1008. {
  1009. $prd = $q * $y->[$yi] + $car;
  1010. $prd -= ($car = int($prd / $BASE)) * $BASE;
  1011. $x->[$xi] += $BASE if ($bar = (($x->[$xi] -= $prd + $bar) < 0));
  1012. }
  1013. if ($x->[-1] < $car + $bar)
  1014. {
  1015. $car = 0; --$q;
  1016. for ($yi = 0, $xi = $#$x-$#$y-1; $yi <= $#$y; ++$yi,++$xi)
  1017. {
  1018. $x->[$xi] -= $BASE
  1019. if ($car = (($x->[$xi] += $y->[$yi] + $car) >= $BASE));
  1020. }
  1021. }
  1022. }
  1023. pop(@$x); unshift(@q, $q);
  1024. }
  1025. if (wantarray)
  1026. {
  1027. @d = ();
  1028. if ($dd != 1)
  1029. {
  1030. $car = 0;
  1031. for $xi (reverse @$x)
  1032. {
  1033. $prd = $car * $BASE + $xi;
  1034. $car = $prd - ($tmp = int($prd / $dd)) * $dd;
  1035. unshift(@d, $tmp);
  1036. }
  1037. }
  1038. else
  1039. {
  1040. @d = @$x;
  1041. }
  1042. @$x = @q;
  1043. my $d = \@d;
  1044. __strip_zeros($x);
  1045. __strip_zeros($d);
  1046. return ($x,$d);
  1047. }
  1048. @$x = @q;
  1049. __strip_zeros($x);
  1050. $x;
  1051. }
  1052. ##############################################################################
  1053. # testing
  1054. sub _acmp
  1055. {
  1056. # internal absolute post-normalized compare (ignore signs)
  1057. # ref to array, ref to array, return <0, 0, >0
  1058. # arrays must have at least one entry; this is not checked for
  1059. my ($c,$cx,$cy) = @_;
  1060. # shortcut for short numbers
  1061. return (($cx->[0] <=> $cy->[0]) <=> 0)
  1062. if scalar @$cx == scalar @$cy && scalar @$cx == 1;
  1063. # fast comp based on number of array elements (aka pseudo-length)
  1064. my $lxy = (scalar @$cx - scalar @$cy)
  1065. # or length of first element if same number of elements (aka difference 0)
  1066. ||
  1067. # need int() here because sometimes the last element is '00018' vs '18'
  1068. (length(int($cx->[-1])) - length(int($cy->[-1])));
  1069. return -1 if $lxy < 0; # already differs, ret
  1070. return 1 if $lxy > 0; # ditto
  1071. # manual way (abort if unequal, good for early ne)
  1072. my $a; my $j = scalar @$cx;
  1073. while (--$j >= 0)
  1074. {
  1075. last if ($a = $cx->[$j] - $cy->[$j]);
  1076. }
  1077. $a <=> 0;
  1078. }
  1079. sub _len
  1080. {
  1081. # compute number of digits in base 10
  1082. # int() because add/sub sometimes leaves strings (like '00005') instead of
  1083. # '5' in this place, thus causing length() to report wrong length
  1084. my $cx = $_[1];
  1085. (@$cx-1)*$BASE_LEN+length(int($cx->[-1]));
  1086. }
  1087. sub _digit
  1088. {
  1089. # return the nth digit, negative values count backward
  1090. # zero is rightmost, so _digit(123,0) will give 3
  1091. my ($c,$x,$n) = @_;
  1092. my $len = _len('',$x);
  1093. $n = $len+$n if $n < 0; # -1 last, -2 second-to-last
  1094. $n = abs($n); # if negative was too big
  1095. $len--; $n = $len if $n > $len; # n to big?
  1096. my $elem = int($n / $BASE_LEN); # which array element
  1097. my $digit = $n % $BASE_LEN; # which digit in this element
  1098. $elem = '0' x $BASE_LEN . @$x[$elem]; # get element padded with 0's
  1099. substr($elem,-$digit-1,1);
  1100. }
  1101. sub _zeros
  1102. {
  1103. # return amount of trailing zeros in decimal
  1104. # check each array elem in _m for having 0 at end as long as elem == 0
  1105. # Upon finding a elem != 0, stop
  1106. my $x = $_[1];
  1107. return 0 if scalar @$x == 1 && $x->[0] == 0;
  1108. my $zeros = 0; my $elem;
  1109. foreach my $e (@$x)
  1110. {
  1111. if ($e != 0)
  1112. {
  1113. $elem = "$e"; # preserve x
  1114. $elem =~ s/.*?(0*$)/$1/; # strip anything not zero
  1115. $zeros *= $BASE_LEN; # elems * 5
  1116. $zeros += length($elem); # count trailing zeros
  1117. last; # early out
  1118. }
  1119. $zeros ++; # real else branch: 50% slower!
  1120. }
  1121. $zeros;
  1122. }
  1123. ##############################################################################
  1124. # _is_* routines
  1125. sub _is_zero
  1126. {
  1127. # return true if arg is zero
  1128. (((scalar @{$_[1]} == 1) && ($_[1]->[0] == 0))) <=> 0;
  1129. }
  1130. sub _is_even
  1131. {
  1132. # return true if arg is even
  1133. (!($_[1]->[0] & 1)) <=> 0;
  1134. }
  1135. sub _is_odd
  1136. {
  1137. # return true if arg is odd
  1138. (($_[1]->[0] & 1)) <=> 0;
  1139. }
  1140. sub _is_one
  1141. {
  1142. # return true if arg is one
  1143. (scalar @{$_[1]} == 1) && ($_[1]->[0] == 1) <=> 0;
  1144. }
  1145. sub _is_two
  1146. {
  1147. # return true if arg is two
  1148. (scalar @{$_[1]} == 1) && ($_[1]->[0] == 2) <=> 0;
  1149. }
  1150. sub _is_ten
  1151. {
  1152. # return true if arg is ten
  1153. (scalar @{$_[1]} == 1) && ($_[1]->[0] == 10) <=> 0;
  1154. }
  1155. sub __strip_zeros
  1156. {
  1157. # internal normalization function that strips leading zeros from the array
  1158. # args: ref to array
  1159. my $s = shift;
  1160. my $cnt = scalar @$s; # get count of parts
  1161. my $i = $cnt-1;
  1162. push @$s,0 if $i < 0; # div might return empty results, so fix it
  1163. return $s if @$s == 1; # early out
  1164. #print "strip: cnt $cnt i $i\n";
  1165. # '0', '3', '4', '0', '0',
  1166. # 0 1 2 3 4
  1167. # cnt = 5, i = 4
  1168. # i = 4
  1169. # i = 3
  1170. # => fcnt = cnt - i (5-2 => 3, cnt => 5-1 = 4, throw away from 4th pos)
  1171. # >= 1: skip first part (this can be zero)
  1172. while ($i > 0) { last if $s->[$i] != 0; $i--; }
  1173. $i++; splice @$s,$i if ($i < $cnt); # $i cant be 0
  1174. $s;
  1175. }
  1176. ###############################################################################
  1177. # check routine to test internal state for corruptions
  1178. sub _check
  1179. {
  1180. # used by the test suite
  1181. my $x = $_[1];
  1182. return "$x is not a reference" if !ref($x);
  1183. # are all parts are valid?
  1184. my $i = 0; my $j = scalar @$x; my ($e,$try);
  1185. while ($i < $j)
  1186. {
  1187. $e = $x->[$i]; $e = 'undef' unless defined $e;
  1188. $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e)";
  1189. last if $e !~ /^[+]?[0-9]+$/;
  1190. $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e) (stringify)";
  1191. last if "$e" !~ /^[+]?[0-9]+$/;
  1192. $try = '=~ /^[\+]?[0-9]+\$/; '."($x, $e) (cat-stringify)";
  1193. last if '' . "$e" !~ /^[+]?[0-9]+$/;
  1194. $try = ' < 0 || >= $BASE; '."($x, $e)";
  1195. last if $e <0 || $e >= $BASE;
  1196. # this test is disabled, since new/bnorm and certain ops (like early out
  1197. # in add/sub) are allowed/expected to leave '00000' in some elements
  1198. #$try = '=~ /^00+/; '."($x, $e)";
  1199. #last if $e =~ /^00+/;
  1200. $i++;
  1201. }
  1202. return "Illegal part '$e' at pos $i (tested: $try)" if $i < $j;
  1203. 0;
  1204. }
  1205. ###############################################################################
  1206. sub _mod
  1207. {
  1208. # if possible, use mod shortcut
  1209. my ($c,$x,$yo) = @_;
  1210. # slow way since $y to big
  1211. if (scalar @$yo > 1)
  1212. {
  1213. my ($xo,$rem) = _div($c,$x,$yo);
  1214. return $rem;
  1215. }
  1216. my $y = $yo->[0];
  1217. # both are single element arrays
  1218. if (scalar @$x == 1)
  1219. {
  1220. $x->[0] %= $y;
  1221. return $x;
  1222. }
  1223. # @y is a single element, but @x has more than one element
  1224. my $b = $BASE % $y;
  1225. if ($b == 0)
  1226. {
  1227. # when BASE % Y == 0 then (B * BASE) % Y == 0
  1228. # (B * BASE) % $y + A % Y => A % Y
  1229. # so need to consider only last element: O(1)
  1230. $x->[0] %= $y;
  1231. }
  1232. elsif ($b == 1)
  1233. {
  1234. # else need to go through all elements: O(N), but loop is a bit simplified
  1235. my $r = 0;
  1236. foreach (@$x)
  1237. {
  1238. $r = ($r + $_) % $y; # not much faster, but heh...
  1239. #$r += $_ % $y; $r %= $y;
  1240. }
  1241. $r = 0 if $r == $y;
  1242. $x->[0] = $r;
  1243. }
  1244. else
  1245. {
  1246. # else need to go through all elements: O(N)
  1247. my $r = 0; my $bm = 1;
  1248. foreach (@$x)
  1249. {
  1250. $r = ($_ * $bm + $r) % $y;
  1251. $bm = ($bm * $b) % $y;
  1252. #$r += ($_ % $y) * $bm;
  1253. #$bm *= $b;
  1254. #$bm %= $y;
  1255. #$r %= $y;
  1256. }
  1257. $r = 0 if $r == $y;
  1258. $x->[0] = $r;
  1259. }
  1260. splice (@$x,1); # keep one element of $x
  1261. $x;
  1262. }
  1263. ##############################################################################
  1264. # shifts
  1265. sub _rsft
  1266. {
  1267. my ($c,$x,$y,$n) = @_;
  1268. if ($n != 10)
  1269. {
  1270. $n = _new($c,$n); return _div($c,$x, _pow($c,$n,$y));
  1271. }
  1272. # shortcut (faster) for shifting by 10)
  1273. # multiples of $BASE_LEN
  1274. my $dst = 0; # destination
  1275. my $src = _num($c,$y); # as normal int
  1276. my $xlen = (@$x-1)*$BASE_LEN+length(int($x->[-1])); # len of x in digits
  1277. if ($src >= $xlen or ($src == $xlen and ! defined $x->[1]))
  1278. {
  1279. # 12345 67890 shifted right by more than 10 digits => 0
  1280. splice (@$x,1); # leave only one element
  1281. $x->[0] = 0; # set to zero
  1282. return $x;
  1283. }
  1284. my $rem = $src % $BASE_LEN; # remainder to shift
  1285. $src = int($src / $BASE_LEN); # source
  1286. if ($rem == 0)
  1287. {
  1288. splice (@$x,0,$src); # even faster, 38.4 => 39.3
  1289. }
  1290. else
  1291. {
  1292. my $len = scalar @$x - $src; # elems to go
  1293. my $vd; my $z = '0'x $BASE_LEN;
  1294. $x->[scalar @$x] = 0; # avoid || 0 test inside loop
  1295. while ($dst < $len)
  1296. {
  1297. $vd = $z.$x->[$src];
  1298. $vd = substr($vd,-$BASE_LEN,$BASE_LEN-$rem);
  1299. $src++;
  1300. $vd = substr($z.$x->[$src],-$rem,$rem) . $vd;
  1301. $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN;
  1302. $x->[$dst] = int($vd);
  1303. $dst++;
  1304. }
  1305. splice (@$x,$dst) if $dst > 0; # kill left-over array elems
  1306. pop @$x if $x->[-1] == 0 && @$x > 1; # kill last element if 0
  1307. } # else rem == 0
  1308. $x;
  1309. }
  1310. sub _lsft
  1311. {
  1312. my ($c,$x,$y,$n) = @_;
  1313. if ($n != 10)
  1314. {
  1315. $n = _new($c,$n); return _mul($c,$x, _pow($c,$n,$y));
  1316. }
  1317. # shortcut (faster) for shifting by 10) since we are in base 10eX
  1318. # multiples of $BASE_LEN:
  1319. my $src = scalar @$x; # source
  1320. my $len = _num($c,$y); # shift-len as normal int
  1321. my $rem = $len % $BASE_LEN; # remainder to shift
  1322. my $dst = $src + int($len/$BASE_LEN); # destination
  1323. my $vd; # further speedup
  1324. $x->[$src] = 0; # avoid first ||0 for speed
  1325. my $z = '0' x $BASE_LEN;
  1326. while ($src >= 0)
  1327. {
  1328. $vd = $x->[$src]; $vd = $z.$vd;
  1329. $vd = substr($vd,-$BASE_LEN+$rem,$BASE_LEN-$rem);
  1330. $vd .= $src > 0 ? substr($z.$x->[$src-1],-$BASE_LEN,$rem) : '0' x $rem;
  1331. $vd = substr($vd,-$BASE_LEN,$BASE_LEN) if length($vd) > $BASE_LEN;
  1332. $x->[$dst] = int($vd);
  1333. $dst--; $src--;
  1334. }
  1335. # set lowest parts to 0
  1336. while ($dst >= 0) { $x->[$dst--] = 0; }
  1337. # fix spurios last zero element
  1338. splice @$x,-1 if $x->[-1] == 0;
  1339. $x;
  1340. }
  1341. sub _pow
  1342. {
  1343. # power of $x to $y
  1344. # ref to array, ref to array, return ref to array
  1345. my ($c,$cx,$cy) = @_;
  1346. if (scalar @$cy == 1 && $cy->[0] == 0)
  1347. {
  1348. splice (@$cx,1); $cx->[0] = 1; # y == 0 => x => 1
  1349. return $cx;
  1350. }
  1351. if ((scalar @$cx == 1 && $cx->[0] == 1) || # x == 1
  1352. (scalar @$cy == 1 && $cy->[0] == 1)) # or y == 1
  1353. {
  1354. return $cx;
  1355. }
  1356. if (scalar @$cx == 1 && $cx->[0] == 0)
  1357. {
  1358. splice (@$cx,1); $cx->[0] = 0; # 0 ** y => 0 (if not y <= 0)
  1359. return $cx;
  1360. }
  1361. my $pow2 = _one();
  1362. my $y_bin = _as_bin($c,$cy); $y_bin =~ s/^0b//;
  1363. my $len = length($y_bin);
  1364. while (--$len > 0)
  1365. {
  1366. _mul($c,$pow2,$cx) if substr($y_bin,$len,1) eq '1'; # is odd?
  1367. _mul($c,$cx,$cx);
  1368. }
  1369. _mul($c,$cx,$pow2);
  1370. $cx;
  1371. }
  1372. sub _nok
  1373. {
  1374. # n over k
  1375. # ref to array, return ref to array
  1376. my ($c,$n,$k) = @_;
  1377. # ( 7 ) 7! 1*2*3*4 * 5*6*7 5 * 6 * 7 6 7
  1378. # ( - ) = --------- = --------------- = --------- = 5 * - * -
  1379. # ( 3 ) (7-3)! 3! 1*2*3*4 * 1*2*3 1 * 2 * 3 2 3
  1380. if (!_is_zero($c,$k))
  1381. {
  1382. my $x = _copy($c,$n);
  1383. _sub($c,$n,$k);
  1384. _inc($c,$n);
  1385. my $f = _copy($c,$n); _inc($c,$f); # n = 5, f = 6, d = 2
  1386. my $d = _two($c);
  1387. while (_acmp($c,$f,$x) <= 0) # f <= n ?
  1388. {
  1389. # n = (n * f / d) == 5 * 6 / 2
  1390. $n = _mul($c,$n,$f); $n = _div($c,$n,$d);
  1391. # f = 7, d = 3
  1392. _inc($c,$f); _inc($c,$d);
  1393. }
  1394. }
  1395. else
  1396. {
  1397. # keep ref to $n and set it to 1
  1398. splice (@$n,1); $n->[0] = 1;
  1399. }
  1400. $n;
  1401. }
  1402. my @factorials = (
  1403. 1,
  1404. 1,
  1405. 2,
  1406. 2*3,
  1407. 2*3*4,
  1408. 2*3*4*5,
  1409. 2*3*4*5*6,
  1410. 2*3*4*5*6*7,
  1411. );
  1412. sub _fac
  1413. {
  1414. # factorial of $x
  1415. # ref to array, return ref to array
  1416. my ($c,$cx) = @_;
  1417. if ((@$cx == 1) && ($cx->[0] <= 7))
  1418. {
  1419. $cx->[0] = $factorials[$cx->[0]]; # 0 => 1, 1 => 1, 2 => 2 etc.
  1420. return $cx;
  1421. }
  1422. if ((@$cx == 1) && # we do this only if $x >= 12 and $x <= 7000
  1423. ($cx->[0] >= 12 && $cx->[0] < 7000))
  1424. {
  1425. # Calculate (k-j) * (k-j+1) ... k .. (k+j-1) * (k + j)
  1426. # See http://blogten.blogspot.com/2007/01/calculating-n.html
  1427. # The above series can be expressed as factors:
  1428. # k * k - (j - i) * 2
  1429. # We cache k*k, and calculate (j * j) as the sum of the first j odd integers
  1430. # This will not work when N exceeds the storage of a Perl scalar, however,
  1431. # in this case the algorithm would be way to slow to terminate, anyway.
  1432. # As soon as the last element of $cx is 0, we split it up and remember
  1433. # how many zeors we got so far. The reason is that n! will accumulate
  1434. # zeros at the end rather fast.
  1435. my $zero_elements = 0;
  1436. # If n is even, set n = n -1
  1437. my $k = _num($c,$cx); my $even = 1;
  1438. if (($k & 1) == 0)
  1439. {
  1440. $even = $k; $k --;
  1441. }
  1442. # set k to the center point
  1443. $k = ($k + 1) / 2;
  1444. # print "k $k even: $even\n";
  1445. # now calculate k * k
  1446. my $k2 = $k * $k;
  1447. my $odd = 1; my $sum = 1;
  1448. my $i = $k - 1;
  1449. # keep reference to x
  1450. my $new_x = _new($c, $k * $even);
  1451. @$cx = @$new_x;
  1452. if ($cx->[0] == 0)
  1453. {
  1454. $zero_elements ++; shift @$cx;
  1455. }
  1456. # print STDERR "x = ", _str($c,$cx),"\n";
  1457. my $BASE2 = int(sqrt($BASE))-1;
  1458. my $j = 1;
  1459. while ($j <= $i)
  1460. {
  1461. my $m = ($k2 - $sum); $odd += 2; $sum += $odd; $j++;
  1462. while ($j <= $i && ($m < $BASE2) && (($k2 - $sum) < $BASE2))
  1463. {
  1464. $m *= ($k2 - $sum);
  1465. $odd += 2; $sum += $odd; $j++;
  1466. # print STDERR "\n k2 $k2 m $m sum $sum odd $odd\n"; sleep(1);
  1467. }
  1468. if ($m < $BASE)
  1469. {
  1470. _mul($c,$cx,[$m]);
  1471. }
  1472. else
  1473. {
  1474. _mul($c,$cx,$c->_new($m));
  1475. }
  1476. if ($cx->[0] == 0)
  1477. {
  1478. $zero_elements ++; shift @$cx;
  1479. }
  1480. # print STDERR "Calculate $k2 - $sum = $m (x = ", _str($c,$cx),")\n";
  1481. }
  1482. # multiply in the zeros again
  1483. unshift @$cx, (0) x $zero_elements;
  1484. return $cx;
  1485. }
  1486. # go forward until $base is exceeded
  1487. # limit is either $x steps (steps == 100 means a result always too high) or
  1488. # $base.
  1489. my $steps = 100; $steps = $cx->[0] if @$cx == 1;
  1490. my $r = 2; my $cf = 3; my $step = 2; my $last = $r;
  1491. while ($r*$cf < $BASE && $step < $steps)
  1492. {
  1493. $last = $r; $r *= $cf++; $step++;
  1494. }
  1495. if ((@$cx == 1) && $step == $cx->[0])
  1496. {
  1497. # completely done, so keep reference to $x and return
  1498. $cx->[0] = $r;
  1499. return $cx;
  1500. }
  1501. # now we must do the left over steps
  1502. my $n; # steps still to do
  1503. if (scalar @$cx == 1)
  1504. {
  1505. $n = $cx->[0];
  1506. }
  1507. else
  1508. {
  1509. $n = _copy($c,$cx);
  1510. }
  1511. # Set $cx to the last result below $BASE (but keep ref to $x)
  1512. $cx->[0] = $last; splice (@$cx,1);
  1513. # As soon as the last element of $cx is 0, we split it up and remember
  1514. # how many zeors we got so far. The reason is that n! will accumulate
  1515. # zeros at the end rather fast.
  1516. my $zero_elements = 0;
  1517. # do left-over steps fit into a scalar?
  1518. if (ref $n eq 'ARRAY')
  1519. {
  1520. # No, so use slower inc() & cmp()
  1521. # ($n is at least $BASE here)
  1522. my $base_2 = int(sqrt($BASE)) - 1;
  1523. #print STDERR "base_2: $base_2\n";
  1524. while ($step < $base_2)
  1525. {
  1526. if ($cx->[0] == 0)
  1527. {
  1528. $zero_elements ++; shift @$cx;
  1529. }
  1530. my $b = $step * ($step + 1); $step += 2;
  1531. _mul($c,$cx,[$b]);
  1532. }
  1533. $step = [$step];
  1534. while (_acmp($c,$step,$n) <= 0)
  1535. {
  1536. if ($cx->[0] == 0)
  1537. {
  1538. $zero_elements ++; shift @$cx;
  1539. }
  1540. _mul($c,$cx,$step); _inc($c,$step);
  1541. }
  1542. }
  1543. else
  1544. {
  1545. # Yes, so we can speed it up slightly
  1546. # print "# left over steps $n\n";
  1547. my $base_4 = int(sqrt(sqrt($BASE))) - 2;
  1548. #print STDERR "base_4: $base_4\n";
  1549. my $n4 = $n - 4;
  1550. while ($step < $n4 && $step < $base_4)
  1551. {
  1552. if ($cx->[0] == 0)
  1553. {
  1554. $zero_elements ++; shift @$cx;
  1555. }
  1556. my $b = $step * ($step + 1); $step += 2; $b *= $step * ($step + 1); $step += 2;
  1557. _mul($c,$cx,[$b]);
  1558. }
  1559. my $base_2 = int(sqrt($BASE)) - 1;
  1560. my $n2 = $n - 2;
  1561. #print STDERR "base_2: $base_2\n";
  1562. while ($step < $n2 && $step < $base_2)
  1563. {
  1564. if ($cx->[0] == 0)
  1565. {
  1566. $zero_elements ++; shift @$cx;
  1567. }
  1568. my $b = $step * ($step + 1); $step += 2;
  1569. _mul($c,$cx,[$b]);
  1570. }
  1571. # do what's left over
  1572. while ($step <= $n)
  1573. {
  1574. _mul($c,$cx,[$step]); $step++;
  1575. if ($cx->[0] == 0)
  1576. {
  1577. $zero_elements ++; shift @$cx;
  1578. }
  1579. }
  1580. }
  1581. # multiply in the zeros again
  1582. unshift @$cx, (0) x $zero_elements;
  1583. $cx; # return result
  1584. }
  1585. #############################################################################
  1586. sub _log_int
  1587. {
  1588. # calculate integer log of $x to base $base
  1589. # ref to array, ref to array - return ref to array
  1590. my ($c,$x,$base) = @_;
  1591. # X == 0 => NaN
  1592. return if (scalar @$x == 1 && $x->[0] == 0);
  1593. # BASE 0 or 1 => NaN
  1594. return if (scalar @$base == 1 && $base->[0] < 2);
  1595. my $cmp = _acmp($c,$x,$base); # X == BASE => 1
  1596. if ($cmp == 0)
  1597. {
  1598. splice (@$x,1); $x->[0] = 1;
  1599. return ($x,1)
  1600. }
  1601. # X < BASE
  1602. if ($cmp < 0)
  1603. {
  1604. splice (@$x,1); $x->[0] = 0;
  1605. return ($x,undef);
  1606. }
  1607. my $x_org = _copy($c,$x); # preserve x
  1608. splice(@$x,1); $x->[0] = 1; # keep ref to $x
  1609. # Compute a guess for the result based on:
  1610. # $guess = int ( length_in_base_10(X) / ( log(base) / log(10) ) )
  1611. my $len = _len($c,$x_org);
  1612. my $log = log($base->[-1]) / log(10);
  1613. # for each additional element in $base, we add $BASE_LEN to the result,
  1614. # based on the observation that log($BASE,10) is BASE_LEN and
  1615. # log(x*y) == log(x) + log(y):
  1616. $log += ((scalar @$base)-1) * $BASE_LEN;
  1617. # calculate now a guess based on the values obtained above:
  1618. my $res = int($len / $log);
  1619. $x->[0] = $res;
  1620. my $trial = _pow ($c, _copy($c, $base), $x);
  1621. my $a = _acmp($c,$trial,$x_org);
  1622. # print STDERR "# trial ", _str($c,$x)," was: $a (0 = exact, -1 too small, +1 too big)\n";
  1623. # found an exact result?
  1624. return ($x,1) if $a == 0;
  1625. if ($a > 0)
  1626. {
  1627. # or too big
  1628. _div($c,$trial,$base); _dec($c, $x);
  1629. while (($a = _acmp($c,$trial,$x_org)) > 0)
  1630. {
  1631. # print STDERR "# big _log_int at ", _str($c,$x), "\n";
  1632. _div($c,$trial,$base); _dec($c, $x);
  1633. }
  1634. # result is now exact (a == 0), or too small (a < 0)
  1635. return ($x, $a == 0 ? 1 : 0);
  1636. }
  1637. # else: result was to small
  1638. _mul($c,$trial,$base);
  1639. # did we now get the right result?
  1640. $a = _acmp($c,$trial,$x_org);
  1641. if ($a == 0) # yes, exactly
  1642. {
  1643. _inc($c, $x);
  1644. return ($x,1);
  1645. }
  1646. return ($x,0) if $a > 0;
  1647. # Result still too small (we should come here only if the estimate above
  1648. # was very off base):
  1649. # Now let the normal trial run obtain the real result
  1650. # Simple loop that increments $x by 2 in each step, possible overstepping
  1651. # the real result
  1652. my $base_mul = _mul($c, _copy($c,$base), $base); # $base * $base
  1653. while (($a = _acmp($c,$trial,$x_org)) < 0)
  1654. {
  1655. # print STDERR "# small _log_int at ", _str($c,$x), "\n";
  1656. _mul($c,$trial,$base_mul); _add($c, $x, [2]);
  1657. }
  1658. my $exact = 1;
  1659. if ($a > 0)
  1660. {
  1661. # overstepped the result
  1662. _dec($c, $x);
  1663. _div($c,$trial,$base);
  1664. $a = _acmp($c,$trial,$x_org);
  1665. if ($a > 0)
  1666. {
  1667. _dec($c, $x);
  1668. }
  1669. $exact = 0 if $a != 0; # a = -1 => not exact result, a = 0 => exact
  1670. }
  1671. ($x,$exact); # return result
  1672. }
  1673. # for debugging:
  1674. use constant DEBUG => 0;
  1675. my $steps = 0;
  1676. sub steps { $steps };
  1677. sub _sqrt
  1678. {
  1679. # square-root of $x in place
  1680. # Compute a guess of the result (by rule of thumb), then improve it via
  1681. # Newton's method.
  1682. my ($c,$x) = @_;
  1683. if (scalar @$x == 1)
  1684. {
  1685. # fits into one Perl scalar, so result can be computed directly
  1686. $x->[0] = int(sqrt($x->[0]));
  1687. return $x;
  1688. }
  1689. my $y = _copy($c,$x);
  1690. # hopefully _len/2 is < $BASE, the -1 is to always undershot the guess
  1691. # since our guess will "grow"
  1692. my $l = int((_len($c,$x)-1) / 2);
  1693. my $lastelem = $x->[-1]; # for guess
  1694. my $elems = scalar @$x - 1;
  1695. # not enough digits, but could have more?
  1696. if ((length($lastelem) <= 3) && ($elems > 1))
  1697. {
  1698. # right-align with zero pad
  1699. my $len = length($lastelem) & 1;
  1700. print "$lastelem => " if DEBUG;
  1701. $lastelem .= substr($x->[-2] . '0' x $BASE_LEN,0,$BASE_LEN);
  1702. # former odd => make odd again, or former even to even again
  1703. $lastelem = $lastelem / 10 if (length($lastelem) & 1) != $len;
  1704. print "$lastelem\n" if DEBUG;
  1705. }
  1706. # construct $x (instead of _lsft($c,$x,$l,10)
  1707. my $r = $l % $BASE_LEN; # 10000 00000 00000 00000 ($BASE_LEN=5)
  1708. $l = int($l / $BASE_LEN);
  1709. print "l = $l " if DEBUG;
  1710. splice @$x,$l; # keep ref($x), but modify it
  1711. # we make the first part of the guess not '1000...0' but int(sqrt($lastelem))
  1712. # that gives us:
  1713. # 14400 00000 => sqrt(14400) => guess first digits to be 120
  1714. # 144000 000000 => sqrt(144000) => guess 379
  1715. print "$lastelem (elems $elems) => " if DEBUG;
  1716. $lastelem = $lastelem / 10 if ($elems & 1 == 1); # odd or even?
  1717. my $g = sqrt($lastelem); $g =~ s/\.//; # 2.345 => 2345
  1718. $r -= 1 if $elems & 1 == 0; # 70 => 7
  1719. # padd with zeros if result is too short
  1720. $x->[$l--] = int(substr($g . '0' x $r,0,$r+1));
  1721. print "now ",$x->[-1] if DEBUG;
  1722. print " would have been ", int('1' . '0' x $r),"\n" if DEBUG;
  1723. # If @$x > 1, we could compute the second elem of the guess, too, to create
  1724. # an even better guess. Not implemented yet. Does it improve performance?
  1725. $x->[$l--] = 0 while ($l >= 0); # all other digits of guess are zero
  1726. print "start x= ",_str($c,$x),"\n" if DEBUG;
  1727. my $two = _two();
  1728. my $last = _zero();
  1729. my $lastlast = _zero();
  1730. $steps = 0 if DEBUG;
  1731. while (_acmp($c,$last,$x) != 0 && _acmp($c,$lastlast,$x) != 0)
  1732. {
  1733. $steps++ if DEBUG;
  1734. $lastlast = _copy($c,$last);
  1735. $last = _copy($c,$x);
  1736. _add($c,$x, _div($c,_copy($c,$y),$x));
  1737. _div($c,$x, $two );
  1738. print " x= ",_str($c,$x),"\n" if DEBUG;
  1739. }
  1740. print "\nsteps in sqrt: $steps, " if DEBUG;
  1741. _dec($c,$x) if _acmp($c,$y,_mul($c,_copy($c,$x),$x)) < 0; # overshot?
  1742. print " final ",$x->[-1],"\n" if DEBUG;
  1743. $x;
  1744. }
  1745. sub _root
  1746. {
  1747. # take n'th root of $x in place (n >= 3)
  1748. my ($c,$x,$n) = @_;
  1749. if (scalar @$x == 1)
  1750. {
  1751. if (scalar @$n > 1)
  1752. {
  1753. # result will always be smaller than 2 so trunc to 1 at once
  1754. $x->[0] = 1;
  1755. }
  1756. else
  1757. {
  1758. # fits into one Perl scalar, so result can be computed directly
  1759. # cannot use int() here, because it rounds wrongly (try
  1760. # (81 ** 3) ** (1/3) to see what I mean)
  1761. #$x->[0] = int( $x->[0] ** (1 / $n->[0]) );
  1762. # round to 8 digits, then truncate result to integer
  1763. $x->[0] = int ( sprintf ("%.8f", $x->[0] ** (1 / $n->[0]) ) );
  1764. }
  1765. return $x;
  1766. }
  1767. # we know now that X is more than one element long
  1768. # if $n is a power of two, we can repeatedly take sqrt($X) and find the
  1769. # proper result, because sqrt(sqrt($x)) == root($x,4)
  1770. my $b = _as_bin($c,$n);
  1771. if ($b =~ /0b1(0+)$/)
  1772. {
  1773. my $count = CORE::length($1); # 0b100 => len('00') => 2
  1774. my $cnt = $count; # counter for loop
  1775. unshift (@$x, 0); # add one element, together with one
  1776. # more below in the loop this makes 2
  1777. while ($cnt-- > 0)
  1778. {
  1779. # 'inflate' $X by adding one element, basically computing
  1780. # $x * $BASE * $BASE. This gives us more $BASE_LEN digits for result
  1781. # since len(sqrt($X)) approx == len($x) / 2.
  1782. unshift (@$x, 0);
  1783. # calculate sqrt($x), $x is now one element to big, again. In the next
  1784. # round we make that two, again.
  1785. _sqrt($c,$x);
  1786. }
  1787. # $x is now one element to big, so truncate result by removing it
  1788. splice (@$x,0,1);
  1789. }
  1790. else
  1791. {
  1792. # trial computation by starting with 2,4,8,16 etc until we overstep
  1793. my $step;
  1794. my $trial = _two();
  1795. # while still to do more than X steps
  1796. do
  1797. {
  1798. $step = _two();
  1799. while (_acmp($c, _pow($c, _copy($c, $trial), $n), $x) < 0)
  1800. {
  1801. _mul ($c, $step, [2]);
  1802. _add ($c, $trial, $step);
  1803. }
  1804. # hit exactly?
  1805. if (_acmp($c, _pow($c, _copy($c, $trial), $n), $x) == 0)
  1806. {
  1807. @$x = @$trial; # make copy while preserving ref to $x
  1808. return $x;
  1809. }
  1810. # overstepped, so go back on step
  1811. _sub($c, $trial, $step);
  1812. } while (scalar @$step > 1 || $step->[0] > 128);
  1813. # reset step to 2
  1814. $step = _two();
  1815. # add two, because $trial cannot be exactly the result (otherwise we would
  1816. # alrady have found it)
  1817. _add($c, $trial, $step);
  1818. # and now add more and more (2,4,6,8,10 etc)
  1819. while (_acmp($c, _pow($c, _copy($c, $trial), $n), $x) < 0)
  1820. {
  1821. _add ($c, $trial, $step);
  1822. }
  1823. # hit not exactly? (overstepped)
  1824. if (_acmp($c, _pow($c, _copy($c, $trial), $n), $x) > 0)
  1825. {
  1826. _dec($c,$trial);
  1827. }
  1828. # hit not exactly? (overstepped)
  1829. # 80 too small, 81 slightly too big, 82 too big
  1830. if (_acmp($c, _pow($c, _copy($c, $trial), $n), $x) > 0)
  1831. {
  1832. _dec ($c, $trial);
  1833. }
  1834. @$x = @$trial; # make copy while preserving ref to $x
  1835. return $x;
  1836. }
  1837. $x;
  1838. }
  1839. ##############################################################################
  1840. # binary stuff
  1841. sub _and
  1842. {
  1843. my ($c,$x,$y) = @_;
  1844. # the shortcut makes equal, large numbers _really_ fast, and makes only a
  1845. # very small performance drop for small numbers (e.g. something with less
  1846. # than 32 bit) Since we optimize for large numbers, this is enabled.
  1847. return $x if _acmp($c,$x,$y) == 0; # shortcut
  1848. my $m = _one(); my ($xr,$yr);
  1849. my $mask = $AND_MASK;
  1850. my $x1 = $x;
  1851. my $y1 = _copy($c,$y); # make copy
  1852. $x = _zero();
  1853. my ($b,$xrr,$yrr);
  1854. use integer;
  1855. while (!_is_zero($c,$x1) && !_is_zero($c,$y1))
  1856. {
  1857. ($x1, $xr) = _div($c,$x1,$mask);
  1858. ($y1, $yr) = _div($c,$y1,$mask);
  1859. # make ints() from $xr, $yr
  1860. # this is when the AND_BITS are greater than $BASE and is slower for
  1861. # small (<256 bits) numbers, but faster for large numbers. Disabled
  1862. # due to KISS principle
  1863. # $b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
  1864. # $b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
  1865. # _add($c,$x, _mul($c, _new( $c, ($xrr & $yrr) ), $m) );
  1866. # 0+ due to '&' doesn't work in strings
  1867. _add($c,$x, _mul($c, [ 0+$xr->[0] & 0+$yr->[0] ], $m) );
  1868. _mul($c,$m,$mask);
  1869. }
  1870. $x;
  1871. }
  1872. sub _xor
  1873. {
  1874. my ($c,$x,$y) = @_;
  1875. return _zero() if _acmp($c,$x,$y) == 0; # shortcut (see -and)
  1876. my $m = _one(); my ($xr,$yr);
  1877. my $mask = $XOR_MASK;
  1878. my $x1 = $x;
  1879. my $y1 = _copy($c,$y); # make copy
  1880. $x = _zero();
  1881. my ($b,$xrr,$yrr);
  1882. use integer;
  1883. while (!_is_zero($c,$x1) && !_is_zero($c,$y1))
  1884. {
  1885. ($x1, $xr) = _div($c,$x1,$mask);
  1886. ($y1, $yr) = _div($c,$y1,$mask);
  1887. # make ints() from $xr, $yr (see _and())
  1888. #$b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
  1889. #$b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
  1890. #_add($c,$x, _mul($c, _new( $c, ($xrr ^ $yrr) ), $m) );
  1891. # 0+ due to '^' doesn't work in strings
  1892. _add($c,$x, _mul($c, [ 0+$xr->[0] ^ 0+$yr->[0] ], $m) );
  1893. _mul($c,$m,$mask);
  1894. }
  1895. # the loop stops when the shorter of the two numbers is exhausted
  1896. # the remainder of the longer one will survive bit-by-bit, so we simple
  1897. # multiply-add it in
  1898. _add($c,$x, _mul($c, $x1, $m) ) if !_is_zero($c,$x1);
  1899. _add($c,$x, _mul($c, $y1, $m) ) if !_is_zero($c,$y1);
  1900. $x;
  1901. }
  1902. sub _or
  1903. {
  1904. my ($c,$x,$y) = @_;
  1905. return $x if _acmp($c,$x,$y) == 0; # shortcut (see _and)
  1906. my $m = _one(); my ($xr,$yr);
  1907. my $mask = $OR_MASK;
  1908. my $x1 = $x;
  1909. my $y1 = _copy($c,$y); # make copy
  1910. $x = _zero();
  1911. my ($b,$xrr,$yrr);
  1912. use integer;
  1913. while (!_is_zero($c,$x1) && !_is_zero($c,$y1))
  1914. {
  1915. ($x1, $xr) = _div($c,$x1,$mask);
  1916. ($y1, $yr) = _div($c,$y1,$mask);
  1917. # make ints() from $xr, $yr (see _and())
  1918. # $b = 1; $xrr = 0; foreach (@$xr) { $xrr += $_ * $b; $b *= $BASE; }
  1919. # $b = 1; $yrr = 0; foreach (@$yr) { $yrr += $_ * $b; $b *= $BASE; }
  1920. # _add($c,$x, _mul($c, _new( $c, ($xrr | $yrr) ), $m) );
  1921. # 0+ due to '|' doesn't work in strings
  1922. _add($c,$x, _mul($c, [ 0+$xr->[0] | 0+$yr->[0] ], $m) );
  1923. _mul($c,$m,$mask);
  1924. }
  1925. # the loop stops when the shorter of the two numbers is exhausted
  1926. # the remainder of the longer one will survive bit-by-bit, so we simple
  1927. # multiply-add it in
  1928. _add($c,$x, _mul($c, $x1, $m) ) if !_is_zero($c,$x1);
  1929. _add($c,$x, _mul($c, $y1, $m) ) if !_is_zero($c,$y1);
  1930. $x;
  1931. }
  1932. sub _as_hex
  1933. {
  1934. # convert a decimal number to hex (ref to array, return ref to string)
  1935. my ($c,$x) = @_;
  1936. # fits into one element (handle also 0x0 case)
  1937. return sprintf("0x%x",$x->[0]) if @$x == 1;
  1938. my $x1 = _copy($c,$x);
  1939. my $es = '';
  1940. my ($xr, $h, $x10000);
  1941. if ($] >= 5.006)
  1942. {
  1943. $x10000 = [ 0x10000 ]; $h = 'h4';
  1944. }
  1945. else
  1946. {
  1947. $x10000 = [ 0x1000 ]; $h = 'h3';
  1948. }
  1949. while (@$x1 != 1 || $x1->[0] != 0) # _is_zero()
  1950. {
  1951. ($x1, $xr) = _div($c,$x1,$x10000);
  1952. $es .= unpack($h,pack('V',$xr->[0]));
  1953. }
  1954. $es = reverse $es;
  1955. $es =~ s/^[0]+//; # strip leading zeros
  1956. '0x' . $es; # return result prepended with 0x
  1957. }
  1958. sub _as_bin
  1959. {
  1960. # convert a decimal number to bin (ref to array, return ref to string)
  1961. my ($c,$x) = @_;
  1962. # fits into one element (and Perl recent enough), handle also 0b0 case
  1963. # handle zero case for older Perls
  1964. if ($] <= 5.005 && @$x == 1 && $x->[0] == 0)
  1965. {
  1966. my $t = '0b0'; return $t;
  1967. }
  1968. if (@$x == 1 && $] >= 5.006)
  1969. {
  1970. my $t = sprintf("0b%b",$x->[0]);
  1971. return $t;
  1972. }
  1973. my $x1 = _copy($c,$x);
  1974. my $es = '';
  1975. my ($xr, $b, $x10000);
  1976. if ($] >= 5.006)
  1977. {
  1978. $x10000 = [ 0x10000 ]; $b = 'b16';
  1979. }
  1980. else
  1981. {
  1982. $x10000 = [ 0x1000 ]; $b = 'b12';
  1983. }
  1984. while (!(@$x1 == 1 && $x1->[0] == 0)) # _is_zero()
  1985. {
  1986. ($x1, $xr) = _div($c,$x1,$x10000);
  1987. $es .= unpack($b,pack('v',$xr->[0]));
  1988. }
  1989. $es = reverse $es;
  1990. $es =~ s/^[0]+//; # strip leading zeros
  1991. '0b' . $es; # return result prepended with 0b
  1992. }
  1993. sub _as_oct
  1994. {
  1995. # convert a decimal number to octal (ref to array, return ref to string)
  1996. my ($c,$x) = @_;
  1997. # fits into one element (handle also 0 case)
  1998. return sprintf("0%o",$x->[0]) if @$x == 1;
  1999. my $x1 = _copy($c,$x);
  2000. my $es = '';
  2001. my $xr;
  2002. my $x1000 = [ 0100000 ];
  2003. while (@$x1 != 1 || $x1->[0] != 0) # _is_zero()
  2004. {
  2005. ($x1, $xr) = _div($c,$x1,$x1000);
  2006. $es .= reverse sprintf("%05o", $xr->[0]);
  2007. }
  2008. $es = reverse $es;
  2009. $es =~ s/^[0]+//; # strip leading zeros
  2010. '0' . $es; # return result prepended with 0
  2011. }
  2012. sub _from_oct
  2013. {
  2014. # convert a octal number to decimal (string, return ref to array)
  2015. my ($c,$os) = @_;
  2016. # for older Perls, play safe
  2017. my $m = [ 0100000 ];
  2018. my $d = 5; # 5 digits at a time
  2019. my $mul = _one();
  2020. my $x = _zero();
  2021. my $len = int( (length($os)-1)/$d ); # $d digit parts, w/o the '0'
  2022. my $val; my $i = -$d;
  2023. while ($len >= 0)
  2024. {
  2025. $val = substr($os,$i,$d); # get oct digits
  2026. $val = CORE::oct($val);
  2027. $i -= $d; $len --;
  2028. my $adder = [ $val ];
  2029. _add ($c, $x, _mul ($c, $adder, $mul ) ) if $val != 0;
  2030. _mul ($c, $mul, $m ) if $len >= 0; # skip last mul
  2031. }
  2032. $x;
  2033. }
  2034. sub _from_hex
  2035. {
  2036. # convert a hex number to decimal (string, return ref to array)
  2037. my ($c,$hs) = @_;
  2038. my $m = _new($c, 0x10000000); # 28 bit at a time (<32 bit!)
  2039. my $d = 7; # 7 digits at a time
  2040. if ($] <= 5.006)
  2041. {
  2042. # for older Perls, play safe
  2043. $m = [ 0x10000 ]; # 16 bit at a time (<32 bit!)
  2044. $d = 4; # 4 digits at a time
  2045. }
  2046. my $mul = _one();
  2047. my $x = _zero();
  2048. my $len = int( (length($hs)-2)/$d ); # $d digit parts, w/o the '0x'
  2049. my $val; my $i = -$d;
  2050. while ($len >= 0)
  2051. {
  2052. $val = substr($hs,$i,$d); # get hex digits
  2053. $val =~ s/^0x// if $len == 0; # for last part only because
  2054. $val = CORE::hex($val); # hex does not like wrong chars
  2055. $i -= $d; $len --;
  2056. my $adder = [ $val ];
  2057. # if the resulting number was to big to fit into one element, create a
  2058. # two-element version (bug found by Mark Lakata - Thanx!)
  2059. if (CORE::length($val) > $BASE_LEN)
  2060. {
  2061. $adder = _new($c,$val);
  2062. }
  2063. _add ($c, $x, _mul ($c, $adder, $mul ) ) if $val != 0;
  2064. _mul ($c, $mul, $m ) if $len >= 0; # skip last mul
  2065. }
  2066. $x;
  2067. }
  2068. sub _from_bin
  2069. {
  2070. # convert a hex number to decimal (string, return ref to array)
  2071. my ($c,$bs) = @_;
  2072. # instead of converting X (8) bit at a time, it is faster to "convert" the
  2073. # number to hex, and then call _from_hex.
  2074. my $hs = $bs;
  2075. $hs =~ s/^[+-]?0b//; # remove sign and 0b
  2076. my $l = length($hs); # bits
  2077. $hs = '0' x (8-($l % 8)) . $hs if ($l % 8) != 0; # padd left side w/ 0
  2078. my $h = '0x' . unpack('H*', pack ('B*', $hs)); # repack as hex
  2079. $c->_from_hex($h);
  2080. }
  2081. ##############################################################################
  2082. # special modulus functions
  2083. sub _modinv
  2084. {
  2085. # modular inverse
  2086. my ($c,$x,$y) = @_;
  2087. my $u = _zero($c); my $u1 = _one($c);
  2088. my $a = _copy($c,$y); my $b = _copy($c,$x);
  2089. # Euclid's Algorithm for bgcd(), only that we calc bgcd() ($a) and the
  2090. # result ($u) at the same time. See comments in BigInt for why this works.
  2091. my $q;
  2092. ($a, $q, $b) = ($b, _div($c,$a,$b)); # step 1
  2093. my $sign = 1;
  2094. while (!_is_zero($c,$b))
  2095. {
  2096. my $t = _add($c, # step 2:
  2097. _mul($c,_copy($c,$u1), $q) , # t = u1 * q
  2098. $u ); # + u
  2099. $u = $u1; # u = u1, u1 = t
  2100. $u1 = $t;
  2101. $sign = -$sign;
  2102. ($a, $q, $b) = ($b, _div($c,$a,$b)); # step 1
  2103. }
  2104. # if the gcd is not 1, then return NaN
  2105. return (undef,undef) unless _is_one($c,$a);
  2106. ($u1, $sign == 1 ? '+' : '-');
  2107. }
  2108. sub _modpow
  2109. {
  2110. # modulus of power ($x ** $y) % $z
  2111. my ($c,$num,$exp,$mod) = @_;
  2112. # in the trivial case,
  2113. if (_is_one($c,$mod))
  2114. {
  2115. splice @$num,0,1; $num->[0] = 0;
  2116. return $num;
  2117. }
  2118. if ((scalar @$num == 1) && (($num->[0] == 0) || ($num->[0] == 1)))
  2119. {
  2120. $num->[0] = 1;
  2121. return $num;
  2122. }
  2123. # $num = _mod($c,$num,$mod); # this does not make it faster
  2124. my $acc = _copy($c,$num); my $t = _one();
  2125. my $expbin = _as_bin($c,$exp); $expbin =~ s/^0b//;
  2126. my $len = length($expbin);
  2127. while (--$len >= 0)
  2128. {
  2129. if ( substr($expbin,$len,1) eq '1') # is_odd
  2130. {
  2131. _mul($c,$t,$acc);
  2132. $t = _mod($c,$t,$mod);
  2133. }
  2134. _mul($c,$acc,$acc);
  2135. $acc = _mod($c,$acc,$mod);
  2136. }
  2137. @$num = @$t;
  2138. $num;
  2139. }
  2140. sub _gcd
  2141. {
  2142. # greatest common divisor
  2143. my ($c,$x,$y) = @_;
  2144. while ( (scalar @$y != 1) || ($y->[0] != 0) ) # while ($y != 0)
  2145. {
  2146. my $t = _copy($c,$y);
  2147. $y = _mod($c, $x, $y);
  2148. $x = $t;
  2149. }
  2150. $x;
  2151. }
  2152. ##############################################################################
  2153. ##############################################################################
  2154. 1;
  2155. __END__
  2156. =head1 NAME
  2157. Math::BigInt::Calc - Pure Perl module to support Math::BigInt
  2158. =head1 SYNOPSIS
  2159. Provides support for big integer calculations. Not intended to be used by other
  2160. modules. Other modules which sport the same functions can also be used to support
  2161. Math::BigInt, like Math::BigInt::GMP or Math::BigInt::Pari.
  2162. =head1 DESCRIPTION
  2163. In order to allow for multiple big integer libraries, Math::BigInt was
  2164. rewritten to use library modules for core math routines. Any module which
  2165. follows the same API as this can be used instead by using the following:
  2166. use Math::BigInt lib => 'libname';
  2167. 'libname' is either the long name ('Math::BigInt::Pari'), or only the short
  2168. version like 'Pari'.
  2169. =head1 STORAGE
  2170. =head1 METHODS
  2171. The following functions MUST be defined in order to support the use by
  2172. Math::BigInt v1.70 or later:
  2173. api_version() return API version, 1 for v1.70, 2 for v1.83
  2174. _new(string) return ref to new object from ref to decimal string
  2175. _zero() return a new object with value 0
  2176. _one() return a new object with value 1
  2177. _two() return a new object with value 2
  2178. _ten() return a new object with value 10
  2179. _str(obj) return ref to a string representing the object
  2180. _num(obj) returns a Perl integer/floating point number
  2181. NOTE: because of Perl numeric notation defaults,
  2182. the _num'ified obj may lose accuracy due to
  2183. machine-dependent floating point size limitations
  2184. _add(obj,obj) Simple addition of two objects
  2185. _mul(obj,obj) Multiplication of two objects
  2186. _div(obj,obj) Division of the 1st object by the 2nd
  2187. In list context, returns (result,remainder).
  2188. NOTE: this is integer math, so no
  2189. fractional part will be returned.
  2190. The second operand will be not be 0, so no need to
  2191. check for that.
  2192. _sub(obj,obj) Simple subtraction of 1 object from another
  2193. a third, optional parameter indicates that the params
  2194. are swapped. In this case, the first param needs to
  2195. be preserved, while you can destroy the second.
  2196. sub (x,y,1) => return x - y and keep x intact!
  2197. _dec(obj) decrement object by one (input is guaranteed to be > 0)
  2198. _inc(obj) increment object by one
  2199. _acmp(obj,obj) <=> operator for objects (return -1, 0 or 1)
  2200. _len(obj) returns count of the decimal digits of the object
  2201. _digit(obj,n) returns the n'th decimal digit of object
  2202. _is_one(obj) return true if argument is 1
  2203. _is_two(obj) return true if argument is 2
  2204. _is_ten(obj) return true if argument is 10
  2205. _is_zero(obj) return true if argument is 0
  2206. _is_even(obj) return true if argument is even (0,2,4,6..)
  2207. _is_odd(obj) return true if argument is odd (1,3,5,7..)
  2208. _copy return a ref to a true copy of the object
  2209. _check(obj) check whether internal representation is still intact
  2210. return 0 for ok, otherwise error message as string
  2211. _from_hex(str) return new object from a hexadecimal string
  2212. _from_bin(str) return new object from a binary string
  2213. _from_oct(str) return new object from an octal string
  2214. _as_hex(str) return string containing the value as
  2215. unsigned hex string, with the '0x' prepended.
  2216. Leading zeros must be stripped.
  2217. _as_bin(str) Like as_hex, only as binary string containing only
  2218. zeros and ones. Leading zeros must be stripped and a
  2219. '0b' must be prepended.
  2220. _rsft(obj,N,B) shift object in base B by N 'digits' right
  2221. _lsft(obj,N,B) shift object in base B by N 'digits' left
  2222. _xor(obj1,obj2) XOR (bit-wise) object 1 with object 2
  2223. Note: XOR, AND and OR pad with zeros if size mismatches
  2224. _and(obj1,obj2) AND (bit-wise) object 1 with object 2
  2225. _or(obj1,obj2) OR (bit-wise) object 1 with object 2
  2226. _mod(obj1,obj2) Return remainder of div of the 1st by the 2nd object
  2227. _sqrt(obj) return the square root of object (truncated to int)
  2228. _root(obj) return the n'th (n >= 3) root of obj (truncated to int)
  2229. _fac(obj) return factorial of object 1 (1*2*3*4..)
  2230. _pow(obj1,obj2) return object 1 to the power of object 2
  2231. return undef for NaN
  2232. _zeros(obj) return number of trailing decimal zeros
  2233. _modinv return inverse modulus
  2234. _modpow return modulus of power ($x ** $y) % $z
  2235. _log_int(X,N) calculate integer log() of X in base N
  2236. X >= 0, N >= 0 (return undef for NaN)
  2237. returns (RESULT, EXACT) where EXACT is:
  2238. 1 : result is exactly RESULT
  2239. 0 : result was truncated to RESULT
  2240. undef : unknown whether result is exactly RESULT
  2241. _gcd(obj,obj) return Greatest Common Divisor of two objects
  2242. The following functions are REQUIRED for an api_version of 2 or greater:
  2243. _1ex($x) create the number 1Ex where x >= 0
  2244. _alen(obj) returns approximate count of the decimal digits of the
  2245. object. This estimate MUST always be greater or equal
  2246. to what _len() returns.
  2247. _nok(n,k) calculate n over k (binomial coefficient)
  2248. The following functions are optional, and can be defined if the underlying lib
  2249. has a fast way to do them. If undefined, Math::BigInt will use pure Perl (hence
  2250. slow) fallback routines to emulate these:
  2251. _signed_or
  2252. _signed_and
  2253. _signed_xor
  2254. Input strings come in as unsigned but with prefix (i.e. as '123', '0xabc'
  2255. or '0b1101').
  2256. So the library needs only to deal with unsigned big integers. Testing of input
  2257. parameter validity is done by the caller, so you need not worry about
  2258. underflow (f.i. in C<_sub()>, C<_dec()>) nor about division by zero or similar
  2259. cases.
  2260. The first parameter can be modified, that includes the possibility that you
  2261. return a reference to a completely different object instead. Although keeping
  2262. the reference and just changing its contents is preferred over creating and
  2263. returning a different reference.
  2264. Return values are always references to objects, strings, or true/false for
  2265. comparison routines.
  2266. =head1 WRAP YOUR OWN
  2267. If you want to port your own favourite c-lib for big numbers to the
  2268. Math::BigInt interface, you can take any of the already existing modules as
  2269. a rough guideline. You should really wrap up the latest BigInt and BigFloat
  2270. testsuites with your module, and replace in them any of the following:
  2271. use Math::BigInt;
  2272. by this:
  2273. use Math::BigInt lib => 'yourlib';
  2274. This way you ensure that your library really works 100% within Math::BigInt.
  2275. =head1 LICENSE
  2276. This program is free software; you may redistribute it and/or modify it under
  2277. the same terms as Perl itself.
  2278. =head1 AUTHORS
  2279. Original math code by Mark Biggar, rewritten by Tels L<http://bloodgate.com/>
  2280. in late 2000.
  2281. Separated from BigInt and shaped API with the help of John Peacock.
  2282. Fixed, speed-up, streamlined and enhanced by Tels 2001 - 2007.
  2283. =head1 SEE ALSO
  2284. L<Math::BigInt>, L<Math::BigFloat>,
  2285. L<Math::BigInt::GMP>, L<Math::BigInt::FastCalc> and L<Math::BigInt::Pari>.
  2286. =cut