aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/brick/math/src/Internal
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/brick/math/src/Internal')
-rw-r--r--vendor/brick/math/src/Internal/Calculator.php44
-rw-r--r--vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php20
-rw-r--r--vendor/brick/math/src/Internal/Calculator/GmpCalculator.php17
-rw-r--r--vendor/brick/math/src/Internal/Calculator/NativeCalculator.php53
4 files changed, 80 insertions, 54 deletions
diff --git a/vendor/brick/math/src/Internal/Calculator.php b/vendor/brick/math/src/Internal/Calculator.php
index b8cecda96..44dd66924 100644
--- a/vendor/brick/math/src/Internal/Calculator.php
+++ b/vendor/brick/math/src/Internal/Calculator.php
@@ -25,7 +25,7 @@ abstract class Calculator
/**
* The maximum exponent value allowed for the pow() method.
*/
- public const MAX_POWER = 1000000;
+ public const MAX_POWER = 1_000_000;
/**
* The alphabet for converting from and to base 2 to 36, lowercase.
@@ -128,7 +128,9 @@ abstract class Calculator
/**
* Compares two numbers.
*
- * @return int [-1, 0, 1] If the first number is less than, equal to, or greater than the second number.
+ * @psalm-return -1|0|1
+ *
+ * @return int -1 if the first number is less than, 0 if equal to, 1 if greater than the second number.
*/
final public function cmp(string $a, string $b) : int
{
@@ -428,16 +430,16 @@ abstract class Calculator
*
* Rounding is performed when the remainder of the division is not zero.
*
- * @param string $a The dividend.
- * @param string $b The divisor, must not be zero.
- * @param int $roundingMode The rounding mode.
+ * @param string $a The dividend.
+ * @param string $b The divisor, must not be zero.
+ * @param RoundingMode $roundingMode The rounding mode.
*
* @throws \InvalidArgumentException If the rounding mode is invalid.
* @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary.
*
* @psalm-suppress ImpureFunctionCall
*/
- final public function divRound(string $a, string $b, int $roundingMode) : string
+ final public function divRound(string $a, string $b, RoundingMode $roundingMode) : string
{
[$quotient, $remainder] = $this->divQR($a, $b);
@@ -571,27 +573,17 @@ abstract class Calculator
$bBin = $this->twosComplement($bBin);
}
- switch ($operator) {
- case 'and':
- $value = $aBin & $bBin;
- $negative = ($aNeg and $bNeg);
- break;
-
- case 'or':
- $value = $aBin | $bBin;
- $negative = ($aNeg or $bNeg);
- break;
-
- case 'xor':
- $value = $aBin ^ $bBin;
- $negative = ($aNeg xor $bNeg);
- break;
+ $value = match ($operator) {
+ 'and' => $aBin & $bBin,
+ 'or' => $aBin | $bBin,
+ 'xor' => $aBin ^ $bBin,
+ };
- // @codeCoverageIgnoreStart
- default:
- throw new \InvalidArgumentException('Invalid bitwise operator.');
- // @codeCoverageIgnoreEnd
- }
+ $negative = match ($operator) {
+ 'and' => $aNeg and $bNeg,
+ 'or' => $aNeg or $bNeg,
+ 'xor' => $aNeg xor $bNeg,
+ };
if ($negative) {
$value = $this->twosComplement($value);
diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php
index 5457a3c98..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,59 +16,58 @@ 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);
}
- /**
- * @psalm-suppress InvalidNullableReturnType
- * @psalm-suppress NullableReturnStatement
- */
+ #[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);
$r = \bcmod($a, $b, 0);
- assert($r !== null);
-
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);
}
- /**
- * @psalm-suppress InvalidNullableReturnType
- * @psalm-suppress NullableReturnStatement
- */
+ #[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 7c679d24d..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.
@@ -23,27 +24,21 @@ class NativeCalculator extends Calculator
* Example: 32-bit: max number 1,999,999,999 (9 digits + carry)
* 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry)
*/
- private int $maxDigits;
+ private readonly int $maxDigits;
/**
* @codeCoverageIgnore
*/
public function __construct()
{
- switch (PHP_INT_SIZE) {
- case 4:
- $this->maxDigits = 9;
- break;
-
- case 8:
- $this->maxDigits = 18;
- break;
-
- default:
- throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.');
- }
+ $this->maxDigits = match (PHP_INT_SIZE) {
+ 4 => 9,
+ 8 => 18,
+ default => throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.')
+ };
}
+ #[Override]
public function add(string $a, string $b) : string
{
/**
@@ -75,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
{
/**
@@ -123,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') {
@@ -161,10 +161,8 @@ class NativeCalculator extends Calculator
if (is_int($nb)) {
// the only division that may overflow is PHP_INT_MIN / -1,
// which cannot happen here as we've already handled a divisor of -1 above.
+ $q = intdiv($na, $nb);
$r = $na % $nb;
- $q = ($na - $r) / $nb;
-
- assert(is_int($q));
return [
(string) $q,
@@ -188,6 +186,7 @@ class NativeCalculator extends Calculator
return [$q, $r];
}
+ #[Override]
public function pow(string $a, int $e) : string
{
if ($e === 0) {
@@ -216,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)
@@ -250,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') {
@@ -497,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);
@@ -536,7 +553,7 @@ class NativeCalculator extends Calculator
/**
* Compares two non-signed large numbers.
*
- * @return int [-1, 0, 1]
+ * @psalm-return -1|0|1
*/
private function doCmp(string $a, string $b) : int
{
@@ -549,7 +566,7 @@ class NativeCalculator extends Calculator
return $cmp;
}
- return \strcmp($a, $b) <=> 0; // enforce [-1, 0, 1]
+ return \strcmp($a, $b) <=> 0; // enforce -1|0|1
}
/**