Skip to content

Commit c5727ef

Browse files
authored
Optimize NativeCalculator::doDiv() (#87)
1 parent 2a8adbd commit c5727ef

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

src/Internal/Calculator/NativeCalculator.php

+16
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,22 @@ private function doDiv(string $a, string $b) : array
488488
$r = $a; // remainder
489489
$z = $y; // focus length, always $y or $y+1
490490

491+
/** @psalm-var numeric-string $b */
492+
$nb = $b * 1; // cast to number
493+
// performance optimization in cases where the remainder will never cause int overflow
494+
if (is_int(($nb - 1) * 10 + 9)) {
495+
$r = (int) \substr($a, 0, $z - 1);
496+
497+
for ($i = $z - 1; $i < $x; $i++) {
498+
$n = $r * 10 + (int) $a[$i];
499+
/** @psalm-var int $nb */
500+
$q .= \intdiv($n, $nb);
501+
$r = $n % $nb;
502+
}
503+
504+
return [\ltrim($q, '0') ?: '0', (string) $r];
505+
}
506+
491507
for (;;) {
492508
$focus = \substr($a, 0, $z);
493509

tests/BigIntegerTest.php

+3
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,9 @@ public static function providerQuotientAndRemainder() : array
12531253
['49283205308081983923480483094304390249024223', '-23981985358744892239240813', '-2055009398548863185', '20719258837232321643854818'],
12541254
['-8378278174814983902084304176539029302438924', '384758527893793829309012129991', '-21775419041855', '-367584271343844173835372665619'],
12551255
['-444444444444444444444444444444444444411111', '-33333333333333', '13333333333333466666666666667', '-33333333300000'],
1256+
1257+
['922337203685477581000000000', '922337203685477580', '1000000000', '1000000000'],
1258+
['922337203685477581000000000', '922337203685477581', '1000000000', '0'],
12561259
];
12571260
}
12581261

0 commit comments

Comments
 (0)