1
0
mirror of https://github.com/danog/math.git synced 2024-11-27 04:14:40 +01:00

Imposed a limit on the power() exponent

Just discovered that bcpow() on HHVM has a weird exponent limit of 2^27+1 (empirically determined), after which it triggers an "exponent too large in raise" error.
Anyway, an exponent of 1,000,000 is more than reasonable for most, if not all, use cases.
This commit is contained in:
Benjamin Morel 2014-09-01 18:38:00 +02:00
parent d4a2a45f25
commit 09a4aa2895
3 changed files with 33 additions and 8 deletions

View File

@ -288,7 +288,9 @@ class BigDecimal implements \Serializable
/**
* Returns this number exponentiated.
*
* @param integer $exponent The exponent, as a positive-or-zero integer.
* The exponent has a limit of 1 million.
*
* @param integer $exponent The exponent, between 0 and 1,000,000.
*
* @return BigDecimal
*/
@ -296,8 +298,12 @@ class BigDecimal implements \Serializable
{
$exponent = (int) $exponent;
if ($exponent < 0) {
throw new \InvalidArgumentException('The exponent cannot be negative.');
if ($exponent < 0 || $exponent > Calculator::MAX_POWER) {
throw new \InvalidArgumentException(sprintf(
'The exponent %d is not in the range 0 to %d.',
$exponent,
Calculator::MAX_POWER
));
}
return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent);

View File

@ -17,6 +17,11 @@ use Brick\Math\RoundingMode;
*/
abstract class Calculator
{
/**
* The maximum exponent value allowed for the pow() method.
*/
const MAX_POWER = 1000000;
/**
* The Calculator instance in use.
*
@ -265,7 +270,7 @@ abstract class Calculator
* Exponentiates a number.
*
* @param string $a The base.
* @param integer $e The exponent, must be a positive-or-zero integer.
* @param integer $e The exponent, validated as an integer between 0 and MAX_POWER.
*
* @return string The power.
*/

View File

@ -1191,8 +1191,8 @@ abstract class BigDecimalTest extends AbstractTestCase
['2', 3, '8', 0],
['3', 3, '27', 0],
['0', 1000000000, '0', 0],
['1', 1000000000, '1', 0],
['0', 1000000, '0', 0],
['1', 1000000, '1', 0],
['-2', 255, '-57896044618658097711785492504343953926634992332820282019728792003956564819968', 0],
[ '2', 256, '115792089237316195423570985008687907853269984665640564039457584007913129639936', 0],
@ -1206,11 +1206,25 @@ abstract class BigDecimalTest extends AbstractTestCase
}
/**
* @dataProvider providerPowerWithInvalidExponentThrowsException
* @expectedException \InvalidArgumentException
*
* @param integer $power
*/
public function testPowerWithNegativeExponentThrowsException()
public function testPowerWithInvalidExponentThrowsException($power)
{
BigDecimal::of(10)->power(-1);
BigDecimal::of(1)->power($power);
}
/**
* @return array
*/
public function providerPowerWithInvalidExponentThrowsException()
{
return [
[-1],
[1000001]
];
}
/**