diff --git a/src/AbelianAdditiveGroup.php b/src/AbelianAdditiveGroup.php deleted file mode 100644 index 4bce544..0000000 --- a/src/AbelianAdditiveGroup.php +++ /dev/null @@ -1,18 +0,0 @@ - - */ -interface AbelianAdditiveGroup -{ - /** - * Returns the element's additive inverse. - * - * @return AbelianAdditiveGroup - */ - public function additiveInverse(); -} diff --git a/src/BigNumber.php b/src/BigNumber.php deleted file mode 100644 index b677a98..0000000 --- a/src/BigNumber.php +++ /dev/null @@ -1,78 +0,0 @@ - - */ -interface BigNumber -{ - /** - * Adds two big numbers - * - * @param BigNumber $b - * @return BigNumber - */ - public function add(BigNumber $b); - - /** - * Substracts $b from $this - * - * @param BigNumber $b - * @return BigNumber - */ - public function sub(BigNumber $b); - - /** - * Multiplies two big numbers - * - * @param BigNumber $b - * @return BigNumber - */ - public function mul(BigNumber $b); - - /** - * Divides $this by $b - * - * @param BigNumber $b - * @return BigNumber - */ - public function div(BigNumber $b); - - /** - * @return boolean - */ - public function isZero(); - - /** - * @return boolean - */ - public function isPositive(); - - /** - * @return boolean - */ - public function isNegative(); - - /** - * @return boolean - */ - public function isInfinite(); - - /** - * Says if this object is a "Not a Number" - * - * @return boolean - */ - public function isNaN(); - - /** - * Equality comparison between this object and $b - * - * @param BigNumber $b - * @return boolean - */ - public function equals(BigNumber $b); -} diff --git a/src/Decimal.php b/src/Decimal.php index f39d2c2..ebcc6c4 100644 --- a/src/Decimal.php +++ b/src/Decimal.php @@ -2,11 +2,6 @@ namespace Litipk\BigNumbers; -use Litipk\BigNumbers\BigNumber as BigNumber; -use Litipk\BigNumbers\IComparableNumber as IComparableNumber; -use Litipk\BigNumbers\AbelianAdditiveGroup as AbelianAdditiveGroup; -use Litipk\BigNumbers\NaN as NaN; -use Litipk\BigNumbers\Infinite as Infinite; use Litipk\Exceptions\NotImplementedException as NotImplementedException; use Litipk\Exceptions\InvalidArgumentTypeException as InvalidArgumentTypeException; @@ -15,8 +10,20 @@ * * @author Andreu Correa Casablanca */ -final class Decimal implements BigNumber, IComparableNumber, AbelianAdditiveGroup +final class Decimal { + /** + * Single instance of "Positive Infinite" + * @var Decimal + */ + private static $pInf = null; + + /** + * Single instance of "Negative Infinite" + * @var Decimal + */ + private static $nInf = null; + /** * Internal numeric value * @var string @@ -32,9 +39,10 @@ final class Decimal implements BigNumber, IComparableNumber, AbelianAdditiveGrou /** * Private constructor */ - private function __construct() + private function __construct($value, $scale) { - + $this->value = $value; + $this->scale = $scale; } /** @@ -45,6 +53,32 @@ private function __clone() } + /** + * Returns a "Positive Infinite" object + * @return Decimal + */ + public static function getPositiveInfinite () + { + if (self::$pInf === null) { + self::$pInf = new Decimal('INF', 0); + } + + return self::$pInf; + } + + /** + * Returns a "Negative Infinite" object + * @return Decimal + */ + public static function getNegativeInfinite () + { + if (self::$nInf === null) { + self::$nInf = new Decimal('-INF', 0); + } + + return self::$nInf; + } + /** * Decimal "constructor". * @@ -53,7 +87,7 @@ private function __clone() */ public static function create($value, $scale = null) { - if (is_int(($value))) { + if (is_int($value)) { return self::fromInteger($value, $scale); } elseif (is_float($value)) { return self::fromFloat($value, $scale); @@ -77,7 +111,7 @@ public static function create($value, $scale = null) */ public static function fromInteger($intValue, $scale = null) { - self::internalConstructorValidation($intValue, $scale); + self::paramsValidation($intValue, $scale); if (!is_int($intValue)) { throw new InvalidArgumentTypeException( @@ -87,13 +121,10 @@ public static function fromInteger($intValue, $scale = null) ); } - $decimal = new Decimal(); - - $decimal->scale = $scale === null ? 0 : $scale; - $decimal->value = $scale === null ? - (string)$intValue : bcadd((string)$intValue, '0', $scale); - - return $decimal; + return new Decimal( + $scale === null ? (string)$intValue : bcadd((string)$intValue, '0', $scale), + $scale === null ? 0 : $scale + ); } /** @@ -103,7 +134,7 @@ public static function fromInteger($intValue, $scale = null) */ public static function fromFloat($fltValue, $scale = null) { - self::internalConstructorValidation($fltValue, $scale); + self::paramsValidation($fltValue, $scale); if (!is_float($fltValue)) { throw new InvalidArgumentTypeException( @@ -114,19 +145,19 @@ public static function fromFloat($fltValue, $scale = null) } if ($fltValue === INF) { - return Infinite::getPositiveInfinite(); + return Decimal::getPositiveInfinite(); } elseif ($fltValue === -INF) { - return Infinite::getNegativeInfinite(); + return Decimal::getNegativeInfinite(); } elseif (is_nan($fltValue)) { - return NaN::getNaN(); + throw new \DomainException( + "To ensure consistency, this class doesn't handle NaN objects." + ); } - $decimal = new Decimal(); - - $decimal->value = number_format($fltValue, $scale === null ? 8 : $scale, '.', ''); - $decimal->scale = $scale === null ? 8 : $scale; - - return $decimal; + return new Decimal( + number_format($fltValue, $scale === null ? 8 : $scale, '.', ''), + $scale === null ? 8 : $scale + ); } /** @@ -136,7 +167,7 @@ public static function fromFloat($fltValue, $scale = null) */ public static function fromString($strValue, $scale = null) { - self::internalConstructorValidation($strValue, $scale); + self::paramsValidation($strValue, $scale); if (!is_string($strValue)) { throw new InvalidArgumentTypeException( @@ -192,12 +223,7 @@ public static function fromString($strValue, $scale = null) $value = self::innerRound($value, $scale); } - $decimal = new Decimal(); - - $decimal->value = $value; - $decimal->scale = $dec_scale; - - return $decimal; + return new Decimal($value, $dec_scale); } /** @@ -210,19 +236,17 @@ public static function fromString($strValue, $scale = null) */ public static function fromDecimal(Decimal $decValue, $scale = null) { - self::internalConstructorValidation($decValue, $scale); + self::paramsValidation($decValue, $scale); // This block protect us from unnecessary additional instances - if ($scale === null || $scale === $decValue->scale) { + if ($scale === null || $scale === $decValue->scale || $decValue->isInfinite()) { return $decValue; } - $decimal = new Decimal(); - - $decimal->value = self::innerRound($decValue->value, $scale); - $decimal->scale = $scale; - - return $decimal; + return new Decimal( + self::innerRound($decValue->value, $scale), + $scale + ); } /** @@ -231,16 +255,26 @@ public static function fromDecimal(Decimal $decValue, $scale = null) * @param integer $scale * @return BigNumber */ - public function add(BigNumber $b, $scale = null) + public function add(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); + self::paramsValidation($b, $scale); - if ($b instanceof Decimal) { - return self::fromString(bcadd($this->value, $b->value, max($this->scale, $b->scale)), $scale); - } else { - // Hack to support new unknown classes. We use the commutative property - return $b->add($this); + if ($this->isInfinite()) { + if (!$b->isInfinite()) { + return $this; + } elseif ($this->isPositive() && $b->isPositive() || $this->isNegative() && $b->isNegative()) { + return $this; + } else { // elseif ($this->isPositive() && $b->isNegative || $this->isNegative() && $b->isPositive()) { + throw new \DomainException("Infinite numbers with opposite signs can't be added"); + } + } elseif ($b->isInfinite()) { + return $b; } + + return self::fromString( + bcadd($this->value, $b->value, max($this->scale, $b->scale)), + $scale + ); } /** @@ -249,38 +283,26 @@ public function add(BigNumber $b, $scale = null) * @param integer $scale * @return BigNumber */ - public function sub(BigNumber $b, $scale = null) + public function sub(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); - - if ($b->isNaN()) { - return $b; - } elseif ($b->isInfinite() && $b->isPositive()) { - return Infinite::getNegativeInfinite(); - } elseif ($b->isInfinite() && $b->isNegative()) { - return Infinite::getPositiveInfinite(); - } elseif ($b instanceof Decimal) { - if ($this->equals($b, $scale)) { - return self::fromInteger( - 0, - $scale !== null ? $scale : max($this->scale, $b->scale) - ); - } + self::paramsValidation($b, $scale); - return self::fromString(bcsub($this->value, $b->value, max($this->scale, $b->scale)), $scale); - } else { - if ($b instanceof AbelianAdditiveGroup) { - - if ($this->isZero()) { - return $b->additiveInverse(); - } else { - // Hack to support new unknown classes. - return $b->additiveInverse()->add($this); - } + if ($this->isInfinite()) { + if (!$b->isInfinite()) { + return $this; + } elseif ($this->isPositive() && $b->isNegative() || $this->isNegative() && $b->isPositive()) { + return $this; + } else { // elseif () { + throw new \DomainException("Infinite numbers with the same sign can't be subtracted"); } - - throw new NotImplementedException("Decimal has no way to substract an object of type ".get_class($b)); + } elseif ($b->isInfinite()) { + return $b->additiveInverse(); } + + return self::fromString( + bcsub($this->value, $b->value, max($this->scale, $b->scale)), + $scale + ); } /** @@ -289,16 +311,26 @@ public function sub(BigNumber $b, $scale = null) * @param integer $scale * @return BigNumber */ - public function mul(BigNumber $b, $scale = null) + public function mul(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); + self::paramsValidation($b, $scale); - if ($b instanceof Decimal) { - return self::fromString(bcmul($this->value, $b->value, $this->scale + $b->scale), $scale); - } else { - // Hack to support new unknown classes. We use the commutative property - return $b->mul($this); + if ($this->isZero() && $b->isInfinite() || $this->isInfinite() && $b->isZero()) { + throw new \DomainException("Zero multiplied by infinite is not allowed."); + } elseif ($this->isZero() && !$b->isInfinite() || !$this->isInfinite() && $b->isZero()) { + return Decimal::fromInteger(0, $scale); + } elseif ($this->isInfinite() || $b->isInfinite()) { + if ($this->isPositive() && $b->isPositive() || $this->isNegative() && $b->isNegative()) { + return self::getPositiveInfinite(); + } else { // elseif ($this->isPositive() && $b->isNegative() || $this->isNegative() && $b->isPositive()) { + return self::getNegativeInfinite(); + } } + + return self::fromString( + bcmul($this->value, $b->value, $this->scale + $b->scale), + $scale + ); } /** @@ -311,23 +343,27 @@ public function mul(BigNumber $b, $scale = null) * @param integer $scale * @return BigNumber */ - public function div(BigNumber $b, $scale = null) + public function div(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); + self::paramsValidation($b, $scale); - if ($b->isNaN()) { - return $b; - } elseif ($b->isZero()) { - return NaN::getNaN(); + if ($b->isZero()) { + throw new \DomainException("Division by zero is not allowed."); } elseif ($this->isZero()) { return self::fromDecimal($this, $scale); - } elseif ($b->isInfinite()) { - return self::fromInteger( - 0, - $scale !== null ? $scale : $this->scale - ); - } elseif ($b instanceof Decimal) { + } elseif ($this->isInfinite()) { + + if ($b->isInfinite()) { + throw new \DomainException("Infinite divided by Infinite is not allowed."); + } elseif ($b->isPositive()) { + return $this; + } else { //if ($b->isNegative()) { + return $this->additiveInverse(); + } + } elseif ($b->isInfinite()) { + return Decimal::fromInteger(0, $scale); + } else { if ($scale !== null) { $divscale = $scale + 1; } else { @@ -362,8 +398,6 @@ public function div(BigNumber $b, $scale = null) bcdiv($this->value, $b->value, $divscale), $divscale-1 ); - } else { - throw new NotImplementedException("Decimal has no way to divide by an object of type ".get_class($b)); } } @@ -375,9 +409,13 @@ public function div(BigNumber $b, $scale = null) public function sqrt($scale = null) { if ($this->isNegative()) { - return NaN::getNaN(); + throw new \DomainException( + "Decimal can't handle square roots of negative numbers (it's only for real numbers)" + ); } elseif ($this->isZero()) { return Decimal::fromDecimal($this, $scale); + } elseif ($this->isInfinite()) { + return $this; } $sqrt_scale = ($scale !== null ? $scale : $this->scale); @@ -401,7 +439,9 @@ public function pow(Decimal $b, $scale = null) if ($b->isPositive()) { return Decimal::fromDecimal($this, $scale); } else { - return NaN::getNaN(); + throw new \DomainException( + "zero can't be powered to zero or negative numbers." + ); } } elseif ($b->isZero()) { return Decimal::fromInteger(1, $scale); @@ -434,7 +474,10 @@ public function pow(Decimal $b, $scale = null) $pow_scale ); } else { // elseif ($this->isNegative()) - return NaN::getNaN(); + throw new NotImplementedException( + "Usually negative numbers can't be powered to non integer numbers. " . + "The cases where is possible are not implemented." + ); } } } @@ -447,9 +490,13 @@ public function pow(Decimal $b, $scale = null) public function log10($scale = null) { if ($this->isNegative()) { - return NaN::getNaN(); + throw new \DomainException( + "Decimal can't handle logarithms of negative numbers (it's only for real numbers)" + ); } elseif ($this->isZero()) { - return Infinite::getNegativeInfinite(); + return Decimal::getNegativeInfinite(); + } elseif ($this->isInfinite()) { + return $this; } return self::fromString( @@ -463,6 +510,10 @@ public function log10($scale = null) */ public function isZero($scale = null) { + if ($this->isInfinite()) { + return false; + } + $cmp_scale = $scale !== null ? $scale : $this->scale; return (bccomp(self::innerRound($this->value, $cmp_scale), '0', $cmp_scale) === 0); @@ -489,16 +540,7 @@ public function isNegative() */ public function isInfinite() { - return false; - } - - /** - * Says if this object is a "Not a Number" - * @return boolean - */ - public function isNaN() - { - return false; + return ($this === self::$pInf || $this === self::$nInf); } /** @@ -507,13 +549,15 @@ public function isNaN() * @param integer $scale * @return boolean */ - public function equals(BigNumber $b, $scale = null) + public function equals(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); + self::paramsValidation($b, $scale); if ($this === $b) { return true; - } elseif ($b instanceof Decimal) { + } elseif ($this->isInfinite()) { + return false; + } else { $cmp_scale = $scale !== null ? $scale : max($this->scale, $b->scale); return ( @@ -523,8 +567,6 @@ public function equals(BigNumber $b, $scale = null) $cmp_scale ) == 0 ); - } else { - return $b->equals($this); } } @@ -534,17 +576,23 @@ public function equals(BigNumber $b, $scale = null) * @param IComparableNumber $b * @return integer */ - public function comp(IComparableNumber $b, $scale = null) + public function comp(Decimal $b, $scale = null) { - self::internalOperatorValidation($b, $scale); + self::paramsValidation($b, $scale); - if ($b === $this) { + if ($this === $b) { return 0; - } elseif ($b instanceof Decimal) { - return bccomp(self::innerRound($this->value, $scale), self::innerRound($b->value, $scale), $scale); - } else { - return -$b->comp($this); + } elseif ($this === self::getPositiveInfinite() || $b === self::getNegativeInfinite()) { + return 1; + } elseif ($this === self::getNegativeInfinite() || $b === self::getPositiveInfinite()) { + return -1; } + + return bccomp( + self::innerRound($this->value, $scale), + self::innerRound($b->value, $scale), + $scale + ); } /** @@ -555,19 +603,19 @@ public function additiveInverse() { if ($this->isZero()) { return $this; + } elseif ($this === self::getPositiveInfinite()) { + return self::$nInf; + } elseif ($this === self::getNegativeInfinite()) { + return self::$pInf; } - $decimal = new Decimal(); - if ($this->isNegative()) { - $decimal->value = substr($this->value, 1); - } elseif ($this->isPositive()) { - $decimal->value = '-' . $this->value; + $value = substr($this->value, 1); + } else { // if ($this->isPositive()) { + $value = '-' . $this->value; } - $decimal->scale = $this->scale; - - return $decimal; + return new Decimal($value, $this->scale); } /** @@ -577,7 +625,7 @@ public function additiveInverse() */ public function round($scale = 0) { - if ($scale >= $this->scale) { + if ($scale >= $this->scale || $this->isInfinite()) { return $this; } @@ -597,42 +645,6 @@ public function abs() return $this->additiveInverse(); } - /** - * @return string - */ - public function __toString() - { - return $this->value; - } - - /** - * Validates basic constructor's arguments - * @param mixed $value - * @param integer $scale - */ - private static function internalConstructorValidation($value, $scale) - { - if ($value === null) { - throw new \InvalidArgumentException('$value must be a non null number'); - } - - if ($scale !== null && (!is_int($scale) || $scale < 0)) { - throw new \InvalidArgumentException('$scale must be a positive integer'); - } - } - - /** - * Validates basic operator's arguments - * @param Decimal $b operand - * @param integer $scale bcmath scale param - */ - private static function internalOperatorValidation(BigNumber $b, $scale) - { - if ($scale !== null && (!is_int($scale) || $scale < 0)) { - throw new \InvalidArgumentException('$scale must be a positive integer'); - } - } - /** * "Rounds" the decimal string to have at most $scale digits after the point * @@ -773,4 +785,28 @@ private static function compute2NRoot($base, $index, $out_scale) return self::innerRound($result, $out_scale); } + + /** + * Validates basic constructor's arguments + * @param mixed $value + * @param integer $scale + */ + private static function paramsValidation ($value, $scale) + { + if ($value === null) { + throw new \InvalidArgumentException('$value must be a non null number'); + } + + if ($scale !== null && (!is_int($scale) || $scale < 0)) { + throw new \InvalidArgumentException('$scale must be a positive integer'); + } + } + + /** + * @return string + */ + public function __toString() + { + return $this->value; + } } diff --git a/src/IComparableNumber.php b/src/IComparableNumber.php deleted file mode 100644 index 33a1d59..0000000 --- a/src/IComparableNumber.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ -interface IComparableNumber -{ - /** - * Compares two objects that allows an "absolute order" - * - * @param IComparableNumber $b - * @return integer (-1 -> lesser, 0 -> equals, 1 -> greater) - */ - public function comp(IComparableNumber $b); -} diff --git a/src/Infinite.php b/src/Infinite.php deleted file mode 100644 index c883ebe..0000000 --- a/src/Infinite.php +++ /dev/null @@ -1,201 +0,0 @@ - - */ -final class Infinite implements BigNumber, IComparableNumber -{ - /** - * Single instance of "Positive Infinite" - * @var Decimal - */ - private static $pInf = null; - - /** - * Single instance of "Negative Infinite" - * @var Decimal - */ - private static $nInf = null; - - /** - * Private constructor - */ - private function __construct() - { - - } - - /** - * Private clone method - */ - private function __clone() - { - - } - - /** - * Returns a "Positive Infinite" object - * @return Decimal - */ - public static function getPositiveInfinite() - { - if (self::$pInf === null) { - self::$pInf = new Infinite(); - } - - return self::$pInf; - } - - /** - * Returns a "Negative Infinite" object - * @return Decimal - */ - public static function getNegativeInfinite() - { - if (self::$nInf === null) { - self::$nInf = new Infinite(); - } - - return self::$nInf; - } - - /** - * @param BigNumber $b - * @return BigNumber - */ - public function add(BigNumber $b) - { - if ($b->isNaN()) { - return $b; - } elseif (!$b->isInfinite()) { - return $this; - } elseif ($this->isPositive() && $b->isPositive() || $this->isNegative() && $b->isNegative()) { - return $this; - } else { - return NaN::getNaN(); - } - } - - /** - * @param BigNumber $b - * @return BigNumber - */ - public function sub(BigNumber $b) - { - if ($b->isNaN()) { - return $b; - } elseif (!$b->isInfinite()) { - return $this; - } elseif ($this->isNegative() && $b->isPositive() || $this->isPositive() && $b->isNegative()) { - return $this; - } else { - return NaN::getNaN(); - } - } - - /** - * @param BigNumber $b - * @return BigNumber - */ - public function mul(BigNumber $b) - { - if ($b->isNaN()) { - return $b; - } elseif ($b->isZero()) { - return NaN::getNaN(); - } elseif ($this->isPositive() && $b->isPositive() || $this->isNegative() && $b->isNegative()) { - return self::getPositiveInfinite(); - } else { // elseif ($this->isNegative() && $b->isPositive() || $this->isPositive() && $b->isNegative()) { - return self::getNegativeInfinite(); - } - } - - /** - * @param BigNumber $b - * @return BigNumber - */ - public function div(BigNumber $b) - { - if ($b->isNaN()) { - return $b; - } elseif ($b->isZero() || $b->isInfinite()) { - return NaN::getNaN(); - } elseif ($this->isPositive() && $b->isPositive() || $this->isNegative() && $b->isNegative()) { - return self::getPositiveInfinite(); - } else { // elseif ($this->isNegative() && $b->isPositive() || $this->isPositive() && $b->isNegative()) { - return self::getNegativeInfinite(); - } - } - - /** - * @return boolean - */ - public function isZero() - { - return false; - } - - /** - * @return boolean - */ - public function isPositive() - { - return ($this === self::getPositiveInfinite()); - } - - /** - * @return boolean - */ - public function isNegative() - { - return ($this === self::getNegativeInfinite()); - } - - /** - * @return boolean - */ - public function isInfinite() - { - return true; - } - - /** - * @return boolean - */ - public function isNaN() - { - return false; - } - - /** - * @param BigNumber $b - * @return boolean - */ - public function equals(BigNumber $b) - { - return $this === $b; - } - - /** - * @param IComparableNumber $b - * @return integer - */ - public function comp(IComparableNumber $b) - { - if ($this === $b) { - return 0; - } elseif ($this === self::getPositiveInfinite()) { - return 1; - } else { // elseif ($this === self::getNegativeInfinite()) - return -1; - } - } -} diff --git a/src/NaN.php b/src/NaN.php deleted file mode 100644 index af04037..0000000 --- a/src/NaN.php +++ /dev/null @@ -1,140 +0,0 @@ -assertTrue($n->add($z)->equals($n)); } - public function testNaNAdd() - { - $nan = NaN::getNaN(); - $one = Decimal::fromInteger(1); - - $this->assertTrue($one->add($nan)->isNaN()); - $this->assertTrue($nan->add($one)->isNaN()); - } - public function testInfiniteAdd() { $one = Decimal::fromInteger(1); - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($one->add($pInf)->equals($pInf)); $this->assertTrue($pInf->add($one)->equals($pInf)); diff --git a/tests/Decimal/DecimalCompTest.php b/tests/Decimal/DecimalCompTest.php index d9be48c..c5034b6 100644 --- a/tests/Decimal/DecimalCompTest.php +++ b/tests/Decimal/DecimalCompTest.php @@ -1,7 +1,6 @@ assertTrue($ten->comp($pInf) === -1); $this->assertTrue($ten->comp($nInf) === 1); diff --git a/tests/Decimal/DecimalDivTest.php b/tests/Decimal/DecimalDivTest.php index 349619b..317ac0b 100644 --- a/tests/Decimal/DecimalDivTest.php +++ b/tests/Decimal/DecimalDivTest.php @@ -1,8 +1,6 @@ assertTrue($one->div($zero)->isNaN()); + $catched = false; + try { + $one->div($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + $this->assertTrue($zero->div($one)->equals($zero)); } @@ -26,22 +31,13 @@ public function testOneDiv() public function testInfiniteDiv() { $one = Decimal::fromInteger(1); - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($one->div($pInf)->isZero()); $this->assertTrue($one->div($nInf)->isZero()); } - public function testNaNDiv() - { - $one = Decimal::fromInteger(1); - $nan = NaN::getNaN(); - - $this->assertTrue($one->div($nan)->isNaN()); - $this->assertTrue($nan->div($one)->isNaN()); - } - public function testBasicDiv() { $one = Decimal::fromInteger(1); diff --git a/tests/Decimal/DecimalEqualsTest.php b/tests/Decimal/DecimalEqualsTest.php index db0f55c..fdb4b17 100644 --- a/tests/Decimal/DecimalEqualsTest.php +++ b/tests/Decimal/DecimalEqualsTest.php @@ -1,7 +1,6 @@ assertTrue(!Decimal::fromInteger(1)->equals(Decimal::fromInteger(2))); - $this->assertTrue(!Decimal::fromInteger(1)->equals(Infinite::getPositiveInfinite())); - $this->assertTrue(!Decimal::fromInteger(1)->equals(Infinite::getNegativeInfinite())); + $this->assertTrue(!Decimal::fromInteger(1)->equals(Decimal::getPositiveInfinite())); + $this->assertTrue(!Decimal::fromInteger(1)->equals(Decimal::getNegativeInfinite())); - $this->assertTrue(!Infinite::getPositiveInfinite()->equals(Decimal::fromInteger(1))); - $this->assertTrue(!Infinite::getNegativeInfinite()->equals(Decimal::fromInteger(1))); + $this->assertTrue(!Decimal::getPositiveInfinite()->equals(Decimal::fromInteger(1))); + $this->assertTrue(!Decimal::getNegativeInfinite()->equals(Decimal::fromInteger(1))); } } diff --git a/tests/Decimal/DecimalFromFloatTest.php b/tests/Decimal/DecimalFromFloatTest.php index b495100..5540508 100644 --- a/tests/Decimal/DecimalFromFloatTest.php +++ b/tests/Decimal/DecimalFromFloatTest.php @@ -19,9 +19,13 @@ public function testInfinites() public function testNaN() { - $NaN = Decimal::fromFloat(INF - INF); - - $this->assertTrue($NaN->isNaN()); + $catched = false; + try { + $NaN = Decimal::fromFloat(INF - INF); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testNoFloat() diff --git a/tests/Decimal/DecimalLog10Test.php b/tests/Decimal/DecimalLog10Test.php index e07586a..ca9300b 100644 --- a/tests/Decimal/DecimalLog10Test.php +++ b/tests/Decimal/DecimalLog10Test.php @@ -16,9 +16,15 @@ public function testZero() public function testNegative() { - $none = Decimal::fromInteger(-1); - - $this->assertTrue($none->log10()->isNaN()); + $nOne = Decimal::fromInteger(-1); + + $catched = false; + try { + $nOne->log10(); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testBigNumbers() diff --git a/tests/Decimal/DecimalMulTest.php b/tests/Decimal/DecimalMulTest.php index c42ff7a..2c15bbd 100644 --- a/tests/Decimal/DecimalMulTest.php +++ b/tests/Decimal/DecimalMulTest.php @@ -1,8 +1,6 @@ assertFalse($n21->isPositive()); } - public function testNaNMul() - { - $nan = NaN::getNaN(); - $one = Decimal::fromInteger(1); - - $this->assertTrue($one->mul($nan)->isNaN()); - $this->assertTrue($nan->mul($one)->isNaN()); - } - public function testInfiniteMul() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $pOne = Decimal::fromInteger(1); $nOne = Decimal::fromInteger(-1); diff --git a/tests/Decimal/DecimalPowTest.php b/tests/Decimal/DecimalPowTest.php index 51baec5..9a9cefd 100644 --- a/tests/Decimal/DecimalPowTest.php +++ b/tests/Decimal/DecimalPowTest.php @@ -1,6 +1,7 @@ assertTrue($zero->pow($nTwo)->isNaN()); - $this->assertTrue($zero->pow($zero)->isNaN()); + $catched = false; + try { + $zero->pow($nTwo); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + + $catched = false; + try { + $zero->pow($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testNoZeroZero() @@ -74,6 +88,12 @@ public function testNegativeSquareRoot() $half = Decimal::fromString('0.5'); $nThree = Decimal::fromInteger(-3); - $this->assertTrue($nThree->pow($half)->isNaN()); + $catched = false; + try { + $nThree->pow($half); + } catch (NotImplementedException $e) { + $catched = true; + } + $this->assertTrue($catched); } } diff --git a/tests/Decimal/DecimalSqrtTest.php b/tests/Decimal/DecimalSqrtTest.php index df48d3c..589174d 100644 --- a/tests/Decimal/DecimalSqrtTest.php +++ b/tests/Decimal/DecimalSqrtTest.php @@ -22,6 +22,12 @@ public function testNearZeroSqrt() public function testNegativeSqrt() { - $this->assertTrue(Decimal::fromInteger(-1)->sqrt()->isNaN()); + $catched = false; + try { + Decimal::fromInteger(-1)->sqrt(); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } } diff --git a/tests/Decimal/DecimalSubTest.php b/tests/Decimal/DecimalSubTest.php index cfc36f3..a33e74b 100644 --- a/tests/Decimal/DecimalSubTest.php +++ b/tests/Decimal/DecimalSubTest.php @@ -1,8 +1,6 @@ assertTrue($one->sub($one)->isZero()); } - public function testNaNSub() - { - $nan = NaN::getNaN(); - $one = Decimal::fromInteger(1); - - $this->assertTrue($one->sub($nan)->isNaN()); - $this->assertTrue($nan->sub($one)->isNaN()); - } - public function testInfiniteSub() { $one = Decimal::fromInteger(1); - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($one->sub($pInf)->equals($nInf)); $this->assertTrue($one->sub($nInf)->equals($pInf)); diff --git a/tests/Infinite/InfiniteAddTest.php b/tests/Infinite/InfiniteAddTest.php index 5f0fb2f..70e4d77 100644 --- a/tests/Infinite/InfiniteAddTest.php +++ b/tests/Infinite/InfiniteAddTest.php @@ -1,40 +1,38 @@ assertTrue($pInf->add($nan)->isNaN()); - $this->assertTrue($nInf->add($nan)->isNaN()); - - $this->assertTrue($nan->add($pInf)->isNaN()); - $this->assertTrue($nan->add($nInf)->isNaN()); - } - public function testInfiniteAdd() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $this->assertTrue($pInf->add($pInf)->equals($pInf)); $this->assertTrue($nInf->add($nInf)->equals($nInf)); - $this->assertTrue($pInf->add($nInf)->isNaN()); - $this->assertTrue($nInf->add($pInf)->isNaN()); + $catched = false; + try { + $pInf->add($nInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + + $catched = false; + try { + $nInf->add($pInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testDecimalSub() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $pTen = Decimal::fromInteger(10); $nTen = Decimal::fromInteger(-10); diff --git a/tests/Infinite/InfiniteCompTest.php b/tests/Infinite/InfiniteCompTest.php index 2696d59..69fcb15 100644 --- a/tests/Infinite/InfiniteCompTest.php +++ b/tests/Infinite/InfiniteCompTest.php @@ -1,13 +1,13 @@ assertTrue($pInf->comp($pInf) === 0); $this->assertTrue($nInf->comp($nInf) === 0); diff --git a/tests/Infinite/InfiniteDivTest.php b/tests/Infinite/InfiniteDivTest.php index 74375bb..904d3d5 100644 --- a/tests/Infinite/InfiniteDivTest.php +++ b/tests/Infinite/InfiniteDivTest.php @@ -1,47 +1,74 @@ assertTrue($pInf->div($nan)->isNaN()); - $this->assertTrue($nInf->div($nan)->isNaN()); - } - public function testZeroDiv() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $zero = Decimal::fromInteger(0); - $this->assertTrue($pInf->div($zero)->isNaN()); - $this->assertTrue($nInf->div($zero)->isNaN()); + $catched = false; + try { + $pInf->div($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + + $catched = false; + try { + $nInf->div($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testInfiniteDiv() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); + + $catched = false; + try { + $pInf->div($pInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + + $catched = false; + try { + $pInf->div($nInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - $this->assertTrue($pInf->div($pInf)->isNaN()); - $this->assertTrue($pInf->div($nInf)->isNaN()); + $catched = false; + try { + $nInf->div($pInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - $this->assertTrue($nInf->div($pInf)->isNaN()); - $this->assertTrue($nInf->div($nInf)->isNaN()); + $catched = false; + try { + $nInf->div($nInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); } public function testSimpleNumberDiv() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $pTen = Decimal::fromInteger(10); $nTen = Decimal::fromInteger(-10); diff --git a/tests/Infinite/InfiniteMulTest.php b/tests/Infinite/InfiniteMulTest.php index e66ee2e..a6b9b05 100644 --- a/tests/Infinite/InfiniteMulTest.php +++ b/tests/Infinite/InfiniteMulTest.php @@ -1,34 +1,46 @@ assertTrue($pInf->mul($zero)->isNaN()); - $this->assertTrue($nInf->mul($zero)->isNaN()); + $catched = false; + try { + $pInf->mul($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - $this->assertTrue($zero->mul($pInf)->isNaN()); - $this->assertTrue($zero->mul($nInf)->isNaN()); - } + $catched = false; + try { + $nInf->mul($zero); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - public function testNaNMul() - { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); - $nan = NaN::getNaN(); + $catched = false; + try { + $zero->mul($pInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - $this->assertTrue($pInf->mul($nan)->isNaN()); - $this->assertTrue($nInf->mul($nan)->isNaN()); + $catched = false; + try { + $zero->mul($nInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); - $this->assertTrue($nan->mul($pInf)->isNaN()); - $this->assertTrue($nan->mul($nInf)->isNaN()); } } diff --git a/tests/Infinite/InfiniteSubTest.php b/tests/Infinite/InfiniteSubTest.php index 44eb345..b43e9f6 100644 --- a/tests/Infinite/InfiniteSubTest.php +++ b/tests/Infinite/InfiniteSubTest.php @@ -1,40 +1,38 @@ assertTrue($pInf->sub($pInf)->isNaN()); - $this->assertTrue($nInf->sub($nInf)->isNaN()); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); + + $catched = false; + try { + $pInf->sub($pInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); + + $catched = false; + try { + $nInf->sub($nInf); + } catch (\DomainException $e) { + $catched = true; + } + $this->assertTrue($catched); $this->assertTrue($pInf->sub($nInf)->equals($pInf)); $this->assertTrue($nInf->sub($pInf)->equals($nInf)); } - public function testNaNSub() - { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); - $nan = NaN::getNaN(); - - $this->assertTrue($pInf->sub($nan)->isNaN()); - $this->assertTrue($nInf->sub($nan)->isNaN()); - - $this->assertTrue($nan->sub($pInf)->isNaN()); - $this->assertTrue($nan->sub($nInf)->isNaN()); - } - public function testDecimalSub() { - $pInf = Infinite::getPositiveInfinite(); - $nInf = Infinite::getNegativeInfinite(); + $pInf = Decimal::getPositiveInfinite(); + $nInf = Decimal::getNegativeInfinite(); $pTen = Decimal::fromInteger(10); $nTen = Decimal::fromInteger(-10); diff --git a/tests/NaNTest.php b/tests/NaNTest.php deleted file mode 100644 index 6e0fa35..0000000 --- a/tests/NaNTest.php +++ /dev/null @@ -1,31 +0,0 @@ -assertTrue(Nan::getNaN()->isZero() === false); - } - - public function testIsPositive() - { - $this->assertTrue(Nan::getNaN()->isPositive() === false); - } - - public function testIsNegative() - { - $this->assertTrue(Nan::getNaN()->isNegative() === false); - } - - public function testIsInfinite() - { - $this->assertTrue(Nan::getNaN()->isInfinite() === false); - } - - public function testEquals() - { - $this->assertFalse(NaN::getNaN()->equals(NaN::getNaN())); - } -}