diff options
Diffstat (limited to 'vendor/brick')
-rw-r--r-- | vendor/brick/math/CHANGELOG.md | 16 | ||||
-rw-r--r-- | vendor/brick/math/composer.json | 2 | ||||
-rw-r--r-- | vendor/brick/math/psalm-baseline.xml | 70 | ||||
-rw-r--r-- | vendor/brick/math/src/BigDecimal.php | 38 | ||||
-rw-r--r-- | vendor/brick/math/src/BigInteger.php | 11 | ||||
-rw-r--r-- | vendor/brick/math/src/BigNumber.php | 10 | ||||
-rw-r--r-- | vendor/brick/math/src/BigRational.php | 13 | ||||
-rw-r--r-- | vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php | 10 | ||||
-rw-r--r-- | vendor/brick/math/src/Internal/Calculator/GmpCalculator.php | 17 | ||||
-rw-r--r-- | vendor/brick/math/src/Internal/Calculator/NativeCalculator.php | 26 |
10 files changed, 209 insertions, 4 deletions
diff --git a/vendor/brick/math/CHANGELOG.md b/vendor/brick/math/CHANGELOG.md index 680fa9ba2..4b47b48dd 100644 --- a/vendor/brick/math/CHANGELOG.md +++ b/vendor/brick/math/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. +## [0.12.3](https://github.com/brick/math/releases/tag/0.12.3) - 2025-02-28 + +✨ **New features** + +- `BigDecimal::getPrecision()` Returns the number of significant digits in a decimal number + +## [0.12.2](https://github.com/brick/math/releases/tag/0.12.2) - 2025-02-26 + +⚡️ **Performance improvements** + +- Division in `NativeCalculator` is now faster for small divisors, thanks to [@Izumi-kun](https://github.com/Izumi-kun) in [#87](https://github.com/brick/math/pull/87). + +👌 **Improvements** + +- Add missing `RoundingNecessaryException` to the `@throws` annotation of `BigNumber::of()` + ## [0.12.1](https://github.com/brick/math/releases/tag/0.12.1) - 2023-11-29 ⚡️ **Performance improvements** diff --git a/vendor/brick/math/composer.json b/vendor/brick/math/composer.json index bd67343ad..f400aa447 100644 --- a/vendor/brick/math/composer.json +++ b/vendor/brick/math/composer.json @@ -24,7 +24,7 @@ "require-dev": { "phpunit/phpunit": "^10.1", "php-coveralls/php-coveralls": "^2.2", - "vimeo/psalm": "5.16.0" + "vimeo/psalm": "6.8.8" }, "autoload": { "psr-4": { diff --git a/vendor/brick/math/psalm-baseline.xml b/vendor/brick/math/psalm-baseline.xml new file mode 100644 index 000000000..112adf451 --- /dev/null +++ b/vendor/brick/math/psalm-baseline.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<files psalm-version="6.8.8@1361cd33008feb3ae2b4a93f1860e14e538ec8c2"> + <file src="src/BigInteger.php"> + <FalsableReturnStatement> + <code><![CDATA[\hex2bin($hex)]]></code> + </FalsableReturnStatement> + <InvalidFalsableReturnType> + <code><![CDATA[string]]></code> + </InvalidFalsableReturnType> + </file> + <file src="src/Exception/DivisionByZeroException.php"> + <ClassMustBeFinal> + <code><![CDATA[DivisionByZeroException]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Exception/IntegerOverflowException.php"> + <ClassMustBeFinal> + <code><![CDATA[IntegerOverflowException]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Exception/NegativeNumberException.php"> + <ClassMustBeFinal> + <code><![CDATA[NegativeNumberException]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Exception/NumberFormatException.php"> + <ClassMustBeFinal> + <code><![CDATA[NumberFormatException]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Exception/RoundingNecessaryException.php"> + <ClassMustBeFinal> + <code><![CDATA[RoundingNecessaryException]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Internal/Calculator/BcMathCalculator.php"> + <ClassMustBeFinal> + <code><![CDATA[BcMathCalculator]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Internal/Calculator/GmpCalculator.php"> + <ClassMustBeFinal> + <code><![CDATA[GmpCalculator]]></code> + </ClassMustBeFinal> + </file> + <file src="src/Internal/Calculator/NativeCalculator.php"> + <ClassMustBeFinal> + <code><![CDATA[NativeCalculator]]></code> + </ClassMustBeFinal> + <InvalidOperand> + <code><![CDATA[$a * $b]]></code> + <code><![CDATA[$a * 1]]></code> + <code><![CDATA[$a + $b]]></code> + <code><![CDATA[$b * 1]]></code> + <code><![CDATA[$b * 1]]></code> + <code><![CDATA[$blockA * $blockB + $carry]]></code> + <code><![CDATA[$blockA + $blockB]]></code> + <code><![CDATA[$blockA + $blockB + $carry]]></code> + <code><![CDATA[$blockA - $blockB]]></code> + <code><![CDATA[$blockA - $blockB - $carry]]></code> + <code><![CDATA[$carry]]></code> + <code><![CDATA[$mul % $complement]]></code> + <code><![CDATA[$mul - $value]]></code> + <code><![CDATA[$nb - 1]]></code> + <code><![CDATA[$sum += $complement]]></code> + <code><![CDATA[($mul - $value) / $complement]]></code> + <code><![CDATA[($nb - 1) * 10]]></code> + </InvalidOperand> + </file> +</files> diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php index 31d22ab30..21d1c4ae3 100644 --- a/vendor/brick/math/src/BigDecimal.php +++ b/vendor/brick/math/src/BigDecimal.php @@ -8,6 +8,7 @@ use Brick\Math\Exception\DivisionByZeroException; use Brick\Math\Exception\MathException; use Brick\Math\Exception\NegativeNumberException; use Brick\Math\Internal\Calculator; +use Override; /** * Immutable, arbitrary-precision signed decimal numbers. @@ -47,6 +48,7 @@ final class BigDecimal extends BigNumber /** * @psalm-pure */ + #[Override] protected static function from(BigNumber $number): static { return $number->toBigDecimal(); @@ -535,6 +537,7 @@ final class BigDecimal extends BigNumber return new BigDecimal(Calculator::get()->neg($this->value), $this->scale); } + #[Override] public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); @@ -552,6 +555,7 @@ final class BigDecimal extends BigNumber return - $that->compareTo($this); } + #[Override] public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); @@ -568,6 +572,33 @@ final class BigDecimal extends BigNumber } /** + * Returns the number of significant digits in the number. + * + * This is the number of digits to both sides of the decimal point, stripped of leading zeros. + * The sign has no impact on the result. + * + * Examples: + * 0 => 0 + * 0.0 => 0 + * 123 => 3 + * 123.456 => 6 + * 0.00123 => 3 + * 0.0012300 => 5 + */ + public function getPrecision(): int + { + $value = $this->value; + + if ($value === '0') { + return 0; + } + + $length = \strlen($value); + + return ($value[0] === '-') ? $length - 1 : $length; + } + + /** * Returns a string representing the integral part of this decimal number. * * Example: `-123.456` => `-123`. @@ -609,6 +640,7 @@ final class BigDecimal extends BigNumber return $this->getFractionalPart() !== \str_repeat('0', $this->scale); } + #[Override] public function toBigInteger() : BigInteger { $zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0); @@ -616,11 +648,13 @@ final class BigDecimal extends BigNumber return self::newBigInteger($zeroScaleDecimal->value); } + #[Override] public function toBigDecimal() : BigDecimal { return $this; } + #[Override] public function toBigRational() : BigRational { $numerator = self::newBigInteger($this->value); @@ -629,6 +663,7 @@ final class BigDecimal extends BigNumber return self::newBigRational($numerator, $denominator, false); } + #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { if ($scale === $this->scale) { @@ -638,16 +673,19 @@ final class BigDecimal extends BigNumber return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode); } + #[Override] public function toInt() : int { return $this->toBigInteger()->toInt(); } + #[Override] public function toFloat() : float { return (float) (string) $this; } + #[Override] public function __toString() : string { if ($this->scale === 0) { diff --git a/vendor/brick/math/src/BigInteger.php b/vendor/brick/math/src/BigInteger.php index 73dcc89a2..72424810d 100644 --- a/vendor/brick/math/src/BigInteger.php +++ b/vendor/brick/math/src/BigInteger.php @@ -10,6 +10,7 @@ use Brick\Math\Exception\MathException; use Brick\Math\Exception\NegativeNumberException; use Brick\Math\Exception\NumberFormatException; use Brick\Math\Internal\Calculator; +use Override; /** * An arbitrary-size integer. @@ -42,6 +43,7 @@ final class BigInteger extends BigNumber /** * @psalm-pure */ + #[Override] protected static function from(BigNumber $number): static { return $number->toBigInteger(); @@ -856,6 +858,7 @@ final class BigInteger extends BigNumber return $this->shiftedRight($n)->isOdd(); } + #[Override] public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); @@ -867,31 +870,37 @@ final class BigInteger extends BigNumber return - $that->compareTo($this); } + #[Override] public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } + #[Override] public function toBigInteger() : BigInteger { return $this; } + #[Override] public function toBigDecimal() : BigDecimal { return self::newBigDecimal($this->value); } + #[Override] public function toBigRational() : BigRational { return self::newBigRational($this, BigInteger::one(), false); } + #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->toBigDecimal()->toScale($scale, $roundingMode); } + #[Override] public function toInt() : int { $intValue = (int) $this->value; @@ -903,6 +912,7 @@ final class BigInteger extends BigNumber return $intValue; } + #[Override] public function toFloat() : float { return (float) $this->value; @@ -1013,6 +1023,7 @@ final class BigInteger extends BigNumber return \hex2bin($hex); } + #[Override] public function __toString() : string { return $this->value; diff --git a/vendor/brick/math/src/BigNumber.php b/vendor/brick/math/src/BigNumber.php index 5a0df7837..5dabd314b 100644 --- a/vendor/brick/math/src/BigNumber.php +++ b/vendor/brick/math/src/BigNumber.php @@ -8,6 +8,7 @@ use Brick\Math\Exception\DivisionByZeroException; use Brick\Math\Exception\MathException; use Brick\Math\Exception\NumberFormatException; use Brick\Math\Exception\RoundingNecessaryException; +use Override; /** * Common interface for arbitrary-precision rational numbers. @@ -51,8 +52,9 @@ abstract class BigNumber implements \JsonSerializable * - strings containing a `.` character or using an exponential notation are returned as BigDecimal * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger * - * @throws NumberFormatException If the format of the number is not valid. + * @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. + * @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding. * * @psalm-pure */ @@ -71,6 +73,9 @@ abstract class BigNumber implements \JsonSerializable } /** + * @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. + * * @psalm-pure */ private static function _of(BigNumber|int|float|string $value) : BigNumber @@ -163,7 +168,7 @@ abstract class BigNumber implements \JsonSerializable /** * Overridden by subclasses to convert a BigNumber to an instance of the subclass. * - * @throws MathException If the value cannot be converted. + * @throws RoundingNecessaryException If the value cannot be converted. * * @psalm-pure */ @@ -502,6 +507,7 @@ abstract class BigNumber implements \JsonSerializable */ abstract public function __toString() : string; + #[Override] final public function jsonSerialize() : string { return $this->__toString(); diff --git a/vendor/brick/math/src/BigRational.php b/vendor/brick/math/src/BigRational.php index fc3060ede..fc36e5573 100644 --- a/vendor/brick/math/src/BigRational.php +++ b/vendor/brick/math/src/BigRational.php @@ -8,6 +8,7 @@ use Brick\Math\Exception\DivisionByZeroException; use Brick\Math\Exception\MathException; use Brick\Math\Exception\NumberFormatException; use Brick\Math\Exception\RoundingNecessaryException; +use Override; /** * An arbitrarily large rational number. @@ -57,6 +58,7 @@ final class BigRational extends BigNumber /** * @psalm-pure */ + #[Override] protected static function from(BigNumber $number): static { return $number->toBigRational(); @@ -320,16 +322,19 @@ final class BigRational extends BigNumber return new BigRational($numerator, $denominator, false); } + #[Override] public function compareTo(BigNumber|int|float|string $that) : int { return $this->minus($that)->getSign(); } + #[Override] public function getSign() : int { return $this->numerator->getSign(); } + #[Override] public function toBigInteger() : BigInteger { $simplified = $this->simplified(); @@ -341,32 +346,38 @@ final class BigRational extends BigNumber return $simplified->numerator; } + #[Override] public function toBigDecimal() : BigDecimal { return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator); } + #[Override] public function toBigRational() : BigRational { return $this; } + #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode); } + #[Override] public function toInt() : int { return $this->toBigInteger()->toInt(); } + #[Override] public function toFloat() : float { $simplified = $this->simplified(); return $simplified->numerator->toFloat() / $simplified->denominator->toFloat(); } + #[Override] public function __toString() : string { $numerator = (string) $this->numerator; @@ -376,7 +387,7 @@ final class BigRational extends BigNumber return $numerator; } - return $this->numerator . '/' . $this->denominator; + return $numerator . '/' . $denominator; } /** diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php index 067085e21..93a27ff81 100644 --- a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Brick\Math\Internal\Calculator; use Brick\Math\Internal\Calculator; +use Override; /** * Calculator implementation built around the bcmath library. @@ -15,31 +16,37 @@ use Brick\Math\Internal\Calculator; */ class BcMathCalculator extends Calculator { + #[Override] public function add(string $a, string $b) : string { return \bcadd($a, $b, 0); } + #[Override] public function sub(string $a, string $b) : string { return \bcsub($a, $b, 0); } + #[Override] public function mul(string $a, string $b) : string { return \bcmul($a, $b, 0); } + #[Override] public function divQ(string $a, string $b) : string { return \bcdiv($a, $b, 0); } + #[Override] public function divR(string $a, string $b) : string { return \bcmod($a, $b, 0); } + #[Override] public function divQR(string $a, string $b) : array { $q = \bcdiv($a, $b, 0); @@ -48,16 +55,19 @@ class BcMathCalculator extends Calculator return [$q, $r]; } + #[Override] public function pow(string $a, int $e) : string { return \bcpow($a, (string) $e, 0); } + #[Override] public function modPow(string $base, string $exp, string $mod) : string { return \bcpowmod($base, $exp, $mod, 0); } + #[Override] public function sqrt(string $n) : string { return \bcsqrt($n, 0); diff --git a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php index 42d4c6927..0e44deeb3 100644 --- a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Brick\Math\Internal\Calculator; use Brick\Math\Internal\Calculator; +use Override; /** * Calculator implementation built around the GMP library. @@ -15,31 +16,37 @@ use Brick\Math\Internal\Calculator; */ class GmpCalculator extends Calculator { + #[Override] public function add(string $a, string $b) : string { return \gmp_strval(\gmp_add($a, $b)); } + #[Override] public function sub(string $a, string $b) : string { return \gmp_strval(\gmp_sub($a, $b)); } + #[Override] public function mul(string $a, string $b) : string { return \gmp_strval(\gmp_mul($a, $b)); } + #[Override] public function divQ(string $a, string $b) : string { return \gmp_strval(\gmp_div_q($a, $b)); } + #[Override] public function divR(string $a, string $b) : string { return \gmp_strval(\gmp_div_r($a, $b)); } + #[Override] public function divQR(string $a, string $b) : array { [$q, $r] = \gmp_div_qr($a, $b); @@ -50,11 +57,13 @@ class GmpCalculator extends Calculator ]; } + #[Override] public function pow(string $a, int $e) : string { return \gmp_strval(\gmp_pow($a, $e)); } + #[Override] public function modInverse(string $x, string $m) : ?string { $result = \gmp_invert($x, $m); @@ -66,41 +75,49 @@ class GmpCalculator extends Calculator return \gmp_strval($result); } + #[Override] public function modPow(string $base, string $exp, string $mod) : string { return \gmp_strval(\gmp_powm($base, $exp, $mod)); } + #[Override] public function gcd(string $a, string $b) : string { return \gmp_strval(\gmp_gcd($a, $b)); } + #[Override] public function fromBase(string $number, int $base) : string { return \gmp_strval(\gmp_init($number, $base)); } + #[Override] public function toBase(string $number, int $base) : string { return \gmp_strval($number, $base); } + #[Override] public function and(string $a, string $b) : string { return \gmp_strval(\gmp_and($a, $b)); } + #[Override] public function or(string $a, string $b) : string { return \gmp_strval(\gmp_or($a, $b)); } + #[Override] public function xor(string $a, string $b) : string { return \gmp_strval(\gmp_xor($a, $b)); } + #[Override] public function sqrt(string $n) : string { return \gmp_strval(\gmp_sqrt($n)); diff --git a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php index 6acd06382..f71c55bed 100644 --- a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Brick\Math\Internal\Calculator; use Brick\Math\Internal\Calculator; +use Override; /** * Calculator implementation using only native PHP code. @@ -37,6 +38,7 @@ class NativeCalculator extends Calculator }; } + #[Override] public function add(string $a, string $b) : string { /** @@ -68,11 +70,13 @@ class NativeCalculator extends Calculator return $result; } + #[Override] public function sub(string $a, string $b) : string { return $this->add($a, $this->neg($b)); } + #[Override] public function mul(string $a, string $b) : string { /** @@ -116,16 +120,19 @@ class NativeCalculator extends Calculator return $result; } + #[Override] public function divQ(string $a, string $b) : string { return $this->divQR($a, $b)[0]; } + #[Override] public function divR(string $a, string $b): string { return $this->divQR($a, $b)[1]; } + #[Override] public function divQR(string $a, string $b) : array { if ($a === '0') { @@ -179,6 +186,7 @@ class NativeCalculator extends Calculator return [$q, $r]; } + #[Override] public function pow(string $a, int $e) : string { if ($e === 0) { @@ -207,6 +215,7 @@ class NativeCalculator extends Calculator /** * Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/ */ + #[Override] public function modPow(string $base, string $exp, string $mod) : string { // special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0) @@ -241,6 +250,7 @@ class NativeCalculator extends Calculator /** * Adapted from https://cp-algorithms.com/num_methods/roots_newton.html */ + #[Override] public function sqrt(string $n) : string { if ($n === '0') { @@ -488,6 +498,22 @@ class NativeCalculator extends Calculator $r = $a; // remainder $z = $y; // focus length, always $y or $y+1 + /** @psalm-var numeric-string $b */ + $nb = $b * 1; // cast to number + // performance optimization in cases where the remainder will never cause int overflow + if (is_int(($nb - 1) * 10 + 9)) { + $r = (int) \substr($a, 0, $z - 1); + + for ($i = $z - 1; $i < $x; $i++) { + $n = $r * 10 + (int) $a[$i]; + /** @psalm-var int $nb */ + $q .= \intdiv($n, $nb); + $r = $n % $nb; + } + + return [\ltrim($q, '0') ?: '0', (string) $r]; + } + for (;;) { $focus = \substr($a, 0, $z); |