%PDF- %PDF-
Direktori : /home/forge/api-takeaseat.eco-n-tech.co.uk/vendor/moontoast/math/src/Moontoast/Math/ |
Current File : //home/forge/api-takeaseat.eco-n-tech.co.uk/vendor/moontoast/math/src/Moontoast/Math/BigNumber.php |
<?php /** * This file is part of the moontoast/math library * * Copyright 2013-2020 Moontoast, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Moontoast\Math; /** * Represents a number for use with Binary Calculator computations * * @link http://www.php.net/bcmath */ class BigNumber extends AbstractBigNumber { /** * Number value, as a string * * @var string */ protected $numberValue; /** * The scale for the current number * * @var int */ protected $numberScale; /** * Constructs a BigNumber object from a string, integer, float, or any * object that may be cast to a string, resulting in a numeric string value * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @param int $scale (optional) Specifies the default number of digits after the decimal * place to be used in operations for this BigNumber * @return void */ public function __construct($number, $scale = null) { if ($scale) { $this->setScale($scale); } $this->setValue($number); } /** * Returns the string value of this BigNumber * * @return string String representation of the number in base 10 */ public function __toString() { return (string) $this->getValue(); } /** * Sets the current number to the absolute value of itself * * @return BigNumber for fluent interface */ public function abs() { $this->numberValue = \ltrim($this->numberValue, '-'); return $this; } /** * Adds the given number to the current number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @link http://www.php.net/bcadd */ public function add($number) { $this->numberValue = \bcadd( $this->numberValue, $this->filterNumber($number), $this->getScale() ); return $this; } /** * Finds the next highest integer value by rounding up the current number * if necessary * * @return BigNumber for fluent interface * @link http://www.php.net/ceil */ public function ceil() { $number = $this->getValue(); if ($this->isPositive()) { // 14 is the magic precision number $number = \bcadd($number, '0', 14); if (\substr($number, -15) != '.00000000000000') { $number = \bcadd($number, '1', 0); } } $this->numberValue = \bcadd($number, '0', 0); return $this; } /** * Compares the current number with the given number * * Returns 0 if the two operands are equal, 1 if the current number is * larger than the given number, -1 otherwise. * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return int * @link http://www.php.net/bccomp */ public function compareTo($number) { $number = $this->filterNumber($number); // http://bugs.php.net/46781 changed how bcmath compares minus zero. for BC purposes we emulate the old // behavior, prior to the bug fix if (preg_match('#^-?0\.0+?$#', $this->numberValue) || preg_match('#^-?0\.0+?$#', $number)) { if ($this->numberValue[0] === $number[0]) { return 0; } return $this->numberValue[0] === '-' ? -1 : 1; } return bccomp( $this->numberValue, $number, $this->getScale() ); } /** * Returns the current value converted to an arbitrary base * * @param int $base The base to convert the current number to * @return string String representation of the number in the given base */ public function convertToBase($base) { return self::convertFromBase10($this->getValue(), $base); } /** * Decreases the value of the current number by one * * @return BigNumber for fluent interface */ public function decrement() { return $this->subtract(1); } /** * Divides the current number by the given number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @throws Exception\ArithmeticException if $number is zero * @link http://www.php.net/bcdiv */ public function divide($number) { $number = $this->filterNumber($number); if ($number == '0') { throw new Exception\ArithmeticException('Division by zero'); } $this->numberValue = \bcdiv( $this->numberValue, $number, $this->getScale() ); return $this; } /** * Finds the next lowest integer value by rounding down the current number * if necessary * * @return BigNumber for fluent interface * @link http://www.php.net/floor */ public function floor() { $number = $this->getValue(); if ($this->isNegative()) { // 14 is the magic precision number $number = \bcadd($number, '0', 14); if (\substr($number, -15) != '.00000000000000') { $number = \bcsub($number, '1', 0); } } $this->numberValue = \bcadd($number, '0', 0); return $this; } /** * Returns the scale used for this BigNumber * * If no scale was set, this will default to the value of bcmath.scale * in php.ini. * * @return int */ public function getScale() { if ($this->numberScale === null) { if (version_compare(PHP_VERSION, '7.3.0') >= 0 || !extension_loaded('bcmath')) { // @codeCoverageIgnoreStart return (string) bcscale(); // @codeCoverageIgnoreEnd } return (string) max(0, strlen(bcadd('0', '0')) - 2); } return $this->numberScale; } /** * Returns the current raw value of this BigNumber * * @return string String representation of the number in base 10 */ public function getValue() { return $this->numberValue; } /** * Increases the value of the current number by one * * @return BigNumber for fluent interface */ public function increment() { return $this->add(1); } /** * Finds the modulus of the current number divided by the given number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @throws Exception\ArithmeticException if $number is zero * @link http://www.php.net/bcmod */ public function mod($number) { $number = $this->filterNumber($number); if ($number == '0') { throw new Exception\ArithmeticException('Division by zero'); } $this->numberValue = \bcmod( $this->numberValue, $number ); return $this; } /** * Multiplies the current number by the given number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @link http://www.php.net/bcmul */ public function multiply($number) { $this->numberValue = \bcmul( $this->numberValue, $this->filterNumber($number), $this->getScale() ); return $this; } /** * Sets the current number to the negative value of itself * * @return BigNumber for fluent interface */ public function negate() { return $this->multiply(-1); } /** * Raises current number to the given number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @link http://www.php.net/bcpow */ public function pow($number) { $this->numberValue = \bcpow( $this->numberValue, $this->filterNumber($number), $this->getScale() ); return $this; } /** * Raises the current number to the $pow, then divides by the $mod * to find the modulus * * This is functionally equivalent to the following code: * * <code> * $n = new BigNumber(1234); * $n->mod($n->pow(32), 2); * </code> * * However, it uses bcpowmod(), so it is faster and can accept larger * parameters. * * @param mixed $pow May be of any type that can be cast to a string * representation of a base 10 number * @param mixed $mod May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @throws Exception\ArithmeticException if $number is zero * @link http://www.php.net/bcpowmod */ public function powMod($pow, $mod) { $mod = $this->filterNumber($mod); if ($mod == '0') { throw new Exception\ArithmeticException('Division by zero'); } $this->numberValue = \bcpowmod( $this->numberValue, $this->filterNumber($pow), $mod, $this->getScale() ); return $this; } /** * Rounds the current number to the nearest integer * * @return BigNumber for fluent interface * @todo Implement precision digits */ public function round() { $original = $this->getValue(); $floored = $this->floor()->getValue(); $diff = \bcsub($original, $floored, 20); if ($this->isNegative()) { $roundedDiff = \round($diff, 0, PHP_ROUND_HALF_DOWN); } else { $roundedDiff = \round($diff); } $this->numberValue = \bcadd( $floored, $roundedDiff, 0 ); return $this; } /** * Sets the scale of this BigNumber * * @param int $scale Specifies the default number of digits after the decimal * place to be used in operations for this BigNumber * @return BigNumber for fluent interface */ public function setScale($scale) { $this->numberScale = (int) $scale; return $this; } /** * Sets the value of this BigNumber to a new value * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface */ public function setValue($number) { // Set the scale for the number to the scale value passed in $number = \bcadd( $this->filterNumber($number), '0', $this->getScale() ); $this->numberValue = $number; return $this; } /** * Shifts the current number $bits to the left * * @param int $bits * @return BigNumber for fluent interface */ public function shiftLeft($bits) { $this->numberValue = \bcmul( $this->numberValue, \bcpow('2', $bits) ); return $this; } /** * Shifts the current number $bits to the right * * @param int $bits * @return BigNumber for fluent interface */ public function shiftRight($bits) { $this->numberValue = \bcdiv( $this->numberValue, \bcpow('2', $bits) ); return $this; } /** * Finds the square root of the current number * * @return BigNumber for fluent interface * @link http://www.php.net/bcsqrt */ public function sqrt() { $this->numberValue = \bcsqrt( $this->numberValue, $this->getScale() ); return $this; } /** * Subtracts the given number from the current number * * @param mixed $number May be of any type that can be cast to a string * representation of a base 10 number * @return BigNumber for fluent interface * @link http://www.php.net/bcsub */ public function subtract($number) { $this->numberValue = \bcsub( $this->numberValue, $this->filterNumber($number), $this->getScale() ); return $this; } /** * Filters a number, converting it to a string value * * @param mixed $number * @return string */ protected function filterNumber($number) { return \filter_var( $number, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ); } }