/** * Protected constructor. Use a factory method to obtain an instance. * * @param BigInteger $numerator The numerator. * @param BigInteger $denominator The denominator. * @param bool $checkDemominator Whether to check the denominator for negative and zero. * * @throws DivisionByZeroException If the denominator is zero. */ protected function __construct(BigInteger $numerator, BigInteger $denominator, $checkDemominator) { if ($checkDemominator) { if ($denominator->isZero()) { throw DivisionByZeroException::denominatorMustNotBeZero(); } if ($denominator->isNegative()) { $numerator = $numerator->negated(); $denominator = $denominator->negated(); } } $this->numerator = $numerator; $this->denominator = $denominator; }
/** * Creates a BigNumber of the given value. * * The concrete return type is dependent on the given value, with the following rules: * * - BigNumber instances are returned as is * - integer numbers are returned as BigInteger * - floating point numbers are returned as BigDecimal * - strings containing a `/` character are returned as BigRational * - strings containing a `.` character or using an exponentional notation are returned as BigDecimal * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger * * @param BigNumber|number|string $value * * @return BigNumber * * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. */ public static function of($value) { if ($value instanceof BigNumber) { return $value; } if (is_int($value)) { return new BigInteger((string) $value); } $value = (string) $value; if (preg_match(self::$regexp, $value, $matches) !== 1) { throw new NumberFormatException('The given value does not represent a valid number.'); } if (isset($matches['denominator'])) { $numerator = self::cleanUp($matches['integral']); $denominator = ltrim($matches['denominator'], '0'); if ($denominator === '') { throw DivisionByZeroException::denominatorMustNotBeZero(); } return new BigRational(new BigInteger($numerator), new BigInteger($denominator), false); } if (isset($matches['fractional']) || isset($matches['exponent'])) { $fractional = isset($matches['fractional']) ? $matches['fractional'] : ''; $exponent = isset($matches['exponent']) ? (int) $matches['exponent'] : 0; $unscaledValue = self::cleanUp($matches['integral'] . $fractional); $scale = strlen($fractional) - $exponent; if ($scale < 0) { if ($unscaledValue !== '0') { $unscaledValue .= str_repeat('0', -$scale); } $scale = 0; } return new BigDecimal($unscaledValue, $scale); } $integral = self::cleanUp($matches['integral']); return new BigInteger($integral); }