From 536e6414e6a64ee1fcb4e89d07abc3f4bc6c40fa Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Fri, 5 Jun 2015 22:17:20 +0200 Subject: [PATCH] Performance optimizations --- src/BigDecimal.php | 22 ++++++++++++++++++++++ src/BigInteger.php | 29 ++++++++++++++++++++++++++--- tests/BigDecimalTest.php | 18 +++++++++++++++--- tests/BigIntegerTest.php | 18 ++++++++++++++---- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/BigDecimal.php b/src/BigDecimal.php index 79e5a8d..61fd4a7 100644 --- a/src/BigDecimal.php +++ b/src/BigDecimal.php @@ -199,6 +199,11 @@ public static function max(...$values) public function plus($that) { $that = BigDecimal::of($that); + + if ($that->value === '0' && $that->scale <= $this->scale) { + return $this; + } + $this->scaleValues($this, $that, $a, $b); $value = Calculator::get()->add($a, $b); @@ -217,6 +222,11 @@ public function plus($that) public function minus($that) { $that = BigDecimal::of($that); + + if ($that->value === '0' && $that->scale <= $this->scale) { + return $this; + } + $this->scaleValues($this, $that, $a, $b); $value = Calculator::get()->sub($a, $b); @@ -236,6 +246,10 @@ public function multipliedBy($that) { $that = BigDecimal::of($that); + if ($that->value === '1' && $that->scale === 0) { + return $this; + } + $value = Calculator::get()->mul($this->value, $that->value); $scale = $this->scale + $that->scale; @@ -269,6 +283,10 @@ public function dividedBy($that, $roundingMode = RoundingMode::UNNECESSARY, $sca } } + if ($that->value === '1' && $scale === $this->scale) { + return $this; + } + $p = $this->valueWithMinScale($that->scale + $scale); $q = $that->valueWithMinScale($this->scale - $scale); @@ -329,6 +347,10 @@ public function power($exponent) { $exponent = (int) $exponent; + if ($exponent === 1) { + return $this; + } + if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { throw new \InvalidArgumentException(sprintf( 'The exponent %d is not in the range 0 to %d.', diff --git a/src/BigInteger.php b/src/BigInteger.php index 016fe6d..f8156d9 100644 --- a/src/BigInteger.php +++ b/src/BigInteger.php @@ -64,7 +64,7 @@ public static function of($value) * The string can optionally be prefixed with the `+` or `-` sign. * * @param string $number The number to parse. - * @param integer $base The base of the number. + * @param integer $base The base of the number, between 2 and 36. * * @return BigInteger * @@ -223,6 +223,11 @@ public static function max(...$values) public function plus($that) { $that = BigInteger::of($that); + + if ($that->value === '0') { + return $this; + } + $value = Calculator::get()->add($this->value, $that->value); return new BigInteger($value); @@ -238,6 +243,11 @@ public function plus($that) public function minus($that) { $that = BigInteger::of($that); + + if ($that->value === '0') { + return $this; + } + $value = Calculator::get()->sub($this->value, $that->value); return new BigInteger($value); @@ -253,6 +263,11 @@ public function minus($that) public function multipliedBy($that) { $that = BigInteger::of($that); + + if ($that->value === '1') { + return $this; + } + $value = Calculator::get()->mul($this->value, $that->value); return new BigInteger($value); @@ -273,7 +288,11 @@ public function dividedBy($that, $roundingMode = RoundingMode::UNNECESSARY) { $that = BigInteger::of($that); - if ($that->isZero()) { + if ($that->value === '1') { + return $this; + } + + if ($that->value === '0') { throw ArithmeticException::divisionByZero(); } @@ -300,7 +319,7 @@ public function divideAndRemainder($that) { $that = BigInteger::of($that); - if ($that->isZero()) { + if ($that->value === '0') { throw ArithmeticException::divisionByZero(); } @@ -327,6 +346,10 @@ public function power($exponent) { $exponent = (int) $exponent; + if ($exponent === 1) { + return $this; + } + if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { throw new \InvalidArgumentException(sprintf( 'The exponent %d is not in the range 0 to %d.', diff --git a/tests/BigDecimalTest.php b/tests/BigDecimalTest.php index 0b2e70d..bc1e35c 100644 --- a/tests/BigDecimalTest.php +++ b/tests/BigDecimalTest.php @@ -396,7 +396,10 @@ public function providerPlus() ['23487837847837428335.322387091', '309049304233535454687656.2392', '309072792071383292115991561587091', 9], ['-234878378478328335.322387091', '309049304233535154687656.232', '309049069355156676359320909612909', 9], ['234878378478328335.3227091', '-3090495154687656.231343344452', '231787883323640679091365755548', 12], - ['-23487837847833435.3231', '-3090495154687656.231343344452', '-26578333002521091554443344452', 12] + ['-23487837847833435.3231', '-3090495154687656.231343344452', '-26578333002521091554443344452', 12], + + ['1234568798347983.2334899238921', '0', '12345687983479832334899238921', 13], + ['-0.00223287647368738736428467863784', '0.000', '-223287647368738736428467863784', 32], ]; } @@ -462,7 +465,10 @@ public function providerMinus() ['234878378477428335.3223334343487091', '309049304233536.2392', '2345693291731947990831334343487091', 16], ['-2348783784774335.32233343434891', '309049304233536.233392', '-265783308900787155572543434891', 14], ['2348783784774335.323232342791', '-309049304233536.556172', '2657833089007871879404342791', 12], - ['-2348783784774335.3232342791', '-309049304233536.556172', '-20397344805407987670622791', 10] + ['-2348783784774335.3232342791', '-309049304233536.556172', '-20397344805407987670622791', 10], + + ['1234568798347983.2334899238921', '0', '12345687983479832334899238921', 13], + ['-0.00223287647368738736428467863784', '0.000', '-223287647368738736428467863784', 32], ]; } @@ -528,7 +534,10 @@ public function providerMultipliedBy() ['589252.156111130', '999.2563989942545241223454', '5888139876152080735720775399923986443020', 31], ['-589252.15611130', '999.256398994254524122354', '-58881398761537794715991163083004200020', 29], ['589252.1561113', '-99.256398994254524122354', '-584870471152079471599116308300420002', 28], - ['-58952.156111', '-9.256398994254524122357', '545684678534996098129205129273627', 27] + ['-58952.156111', '-9.256398994254524122357', '545684678534996098129205129273627', 27], + + ['0.1235437849158495728979344999999999999', '1', '1235437849158495728979344999999999999', 37], + ['-1.324985980890283098409328999999999999', '1', '-1324985980890283098409328999999999999', 36], ]; } @@ -559,6 +568,9 @@ public function providerDividedBy() ['-7', '0.2', null, RoundingMode::UNNECESSARY, '-35', 0], ['-7', '-0.2', null, RoundingMode::UNNECESSARY, '35', 0], + ['1324794783847839472983.343898', '1', null, RoundingMode::UNNECESSARY, '1324794783847839472983343898', 6], + ['-32479478384783947298.3343898', '1', null, RoundingMode::UNNECESSARY, '-324794783847839472983343898', 7], + ['1.5', '2', 2, RoundingMode::UNNECESSARY, '75', 2], ['0.123456789', '0.00244140625', 10, RoundingMode::UNNECESSARY, '505679007744', 10], ['1.234', '123.456', 50, RoundingMode::DOWN, '999546397096941420425090720580611715914981855883', 50], diff --git a/tests/BigIntegerTest.php b/tests/BigIntegerTest.php index 4c0a1b7..677cff3 100644 --- a/tests/BigIntegerTest.php +++ b/tests/BigIntegerTest.php @@ -402,8 +402,11 @@ public function testPlus($a, $b, $r) public function providerPlus() { return [ - ['123456', '-123456', '0'], - ['-123456789', '123456789', '0'], + ['5165450198704521651351654564564089798441', '0', '5165450198704521651351654564564089798441'], + ['-5165450198704521651351654564564089798441', '0', '-5165450198704521651351654564564089798441'], + ['5165450198704521651351654564564089798441', '-5165450198704521651351654564564089798441', '0'], + ['-5165450198704521651351654564564089798441', '5165450198704521651351654564564089798441', '0'], + ['3493049309220392055810', '9918493493849898938928310121', '9918496986899208159320365931'], ['546254089287665464650654', '-4654654565726542654005465', '-4108400476438877189354811'], ['-54654654625426504062224', '406546504670332465465435004', '406491850015707038961372780'], @@ -429,6 +432,11 @@ public function testMinus($a, $b, $r) public function providerMinus() { return [ + ['5165450198704521651351654564564089798441', '0', '5165450198704521651351654564564089798441'], + ['-5165450198704521651351654564564089798441', '0', '-5165450198704521651351654564564089798441'], + ['0', '5165450198704521651351654564564089798441', '-5165450198704521651351654564564089798441'], + ['0', '-5165450198704521651351654564564089798441', '5165450198704521651351654564564089798441'], + ['879798276565798787646', '2345178709879804654605406456', '-2345177830081528088806618810'], ['99465465545004066406868767', '-79870987954654608076067608768', '79970453420199612142474477535'], ['-46465465478979879230745664', '21316504468760001807687078994', '-21362969934238981686917824658'], @@ -454,8 +462,8 @@ public function testMultipliedBy($a, $b, $r) public function providerMultipliedBy() { return [ - ['123456789', '1', '123456789'], - ['123456789', '-1', '-123456789'], + ['123456789098765432101234567890987654321', '1', '123456789098765432101234567890987654321'], + ['123456789098765432101234567890987654321', '-1', '-123456789098765432101234567890987654321'], ['15892588375910581333', '2485910409339228962451', '39507550875019745254366764864945838527183'], ['341581435989834012309', '-91050393818389238433', '-31101124267925302088072082300643257871797'], ['-1204902920503999920003', '1984389583950290232332', '-2390996805119422027350037939263960284136996'], @@ -481,6 +489,8 @@ public function testDividedBy($a, $b, $r) public function providerDividedBy() { return [ + ['123456789098765432101234567890987654321', '1', '123456789098765432101234567890987654321'], + ['123456789098765432101234567890987654321', '-1', '-123456789098765432101234567890987654321'], ['1282493059039502950823948435791053205342314', '24342491090593053', '52685366270303839158198740'], ['1000000000000000000000000000000000000000000000', '7777777777777777', '128571428571428584285714285714'], ['999999999999999999999999999999999999999999999', '22221222222', '45002025091579141312274843781092897'],