diff --git a/composer.json b/composer.json index 86f99ae..951181d 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "require-dev": { "phpunit/phpunit": "^9.5.0", "spryker/code-sniffer": "@stable", - "phpstan/phpstan": "^1.0.0" + "phpstan/phpstan": "^2.1.0" }, "autoload": { "psr-4": { diff --git a/phpstan.neon b/phpstan.neon index cdcfb1f..7e73a4f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,6 +2,7 @@ parameters: level: 8 paths: - src/ - checkMissingIterableValueType: false ignoreErrors: - '#Unsafe usage of new static\(\).#' + - + identifier: missingType.iterableValue diff --git a/src/Decimal.php b/src/Decimal.php index b6cfb1e..8474572 100644 --- a/src/Decimal.php +++ b/src/Decimal.php @@ -242,7 +242,7 @@ public function compareTo($value): int $decimal = static::create($value); $scale = max($this->scale(), $decimal->scale()); - return bccomp($this, $decimal, $scale); + return bccomp($this->toNumericString(), $decimal->toNumericString(), $scale); } /** @@ -258,7 +258,7 @@ public function add($value, ?int $scale = null) $decimal = static::create($value); $scale = $this->resultScale($this, $decimal, $scale); - return new static(bcadd($this, $decimal, $scale)); + return new static(bcadd($this->toNumericString(), $decimal->toNumericString(), $scale)); } /** @@ -296,7 +296,7 @@ public function subtract($value, ?int $scale = null) $decimal = static::create($value); $scale = $this->resultScale($this, $decimal, $scale); - return new static(bcsub($this, $decimal, $scale)); + return new static(bcsub($this->toNumericString(), $decimal->toNumericString(), $scale)); } /** @@ -406,7 +406,7 @@ public function multiply($value, ?int $scale = null) $scale = $this->scale() + $decimal->scale(); } - return new static(bcmul($this, $decimal, $scale)); + return new static(bcmul($this->toNumericString(), $decimal->toNumericString(), $scale)); } /** @@ -426,7 +426,7 @@ public function divide($value, int $scale) throw new DivisionByZeroError('Cannot divide by zero. Only Chuck Norris can!'); } - return new static(bcdiv($this, $decimal, $scale)); + return new static(bcdiv($this->toNumericString(), $decimal->toNumericString(), $scale)); } /** @@ -443,7 +443,10 @@ public function pow($exponent, ?int $scale = null) $scale = $this->scale(); } - return new static(bcpow($this, (string)$exponent, $scale)); + /** @var numeric-string $exp */ + $exp = (string)$exponent; + + return new static(bcpow($this->toNumericString(), $exp, $scale)); } /** @@ -459,7 +462,7 @@ public function sqrt(?int $scale = null) $scale = $this->scale(); } - return new static(bcsqrt($this, $scale)); + return new static(bcsqrt($this->toNumericString(), $scale)); } /** @@ -475,11 +478,10 @@ public function mod($value, ?int $scale = null) if ($scale === null) { $scale = $this->scale(); } - if (version_compare(PHP_VERSION, '7.2') < 0) { - return new static(bcmod($this, (string)$value)); - } + /** @var numeric-string $mod */ + $mod = (string)$value; - return new static(bcmod($this, (string)$value, $scale)); + return new static(bcmod($this->toNumericString(), $mod, $scale)); } /** @@ -492,19 +494,21 @@ public function round(int $scale = 0, int $roundMode = self::ROUND_HALF_UP) { $exponent = $scale + 1; + /** @var numeric-string $e */ $e = bcpow('10', (string)$exponent); + $self = $this->toNumericString(); switch ($roundMode) { case static::ROUND_FLOOR: - $v = bcdiv(bcadd(bcmul($this, $e, 0), $this->isNegative() ? '-9' : '0'), $e, 0); + $v = bcdiv(bcadd(bcmul($self, $e, 0), $this->isNegative() ? '-9' : '0'), $e, 0); break; case static::ROUND_CEIL: - $v = bcdiv(bcadd(bcmul($this, $e, 0), $this->isNegative() ? '0' : '9'), $e, 0); + $v = bcdiv(bcadd(bcmul($self, $e, 0), $this->isNegative() ? '0' : '9'), $e, 0); break; case static::ROUND_HALF_UP: default: - $v = bcdiv(bcadd(bcmul($this, $e, 0), $this->isNegative() ? '-5' : '5'), $e, $scale); + $v = bcdiv(bcadd(bcmul($self, $e, 0), $this->isNegative() ? '-5' : '5'), $e, $scale); } return new static($v); @@ -593,7 +597,14 @@ public function toInt(): int */ public function isBigInteger(): bool { - return bccomp($this->integralPart, (string)PHP_INT_MAX) === 1 || bccomp($this->integralPart, (string)PHP_INT_MIN) === -1; + /** @var numeric-string $integral */ + $integral = $this->integralPart; + /** @var numeric-string $max */ + $max = (string)PHP_INT_MAX; + /** @var numeric-string $min */ + $min = (string)PHP_INT_MIN; + + return bccomp($integral, $max) === 1 || bccomp($integral, $min) === -1; } /** @@ -601,8 +612,15 @@ public function isBigInteger(): bool */ public function isBigDecimal(): bool { + /** @var numeric-string $fractional */ + $fractional = $this->fractionalPart; + /** @var numeric-string $max */ + $max = (string)PHP_INT_MAX; + /** @var numeric-string $min */ + $min = (string)PHP_INT_MIN; + return $this->isBigInteger() || - bccomp($this->fractionalPart, (string)PHP_INT_MAX) === 1 || bccomp($this->fractionalPart, (string)PHP_INT_MIN) === -1; + bccomp($fractional, $max) === 1 || bccomp($fractional, $min) === -1; } /** @@ -686,6 +704,15 @@ public function __toString(): string return $this->toString(); } + /** + * @return numeric-string + */ + protected function toNumericString(): string + { + /** @var numeric-string */ + return $this->toString(); + } + /** * Get the printable version of this object * @@ -829,7 +856,11 @@ protected function fromScientific(string $value, ?int $scale): void $this->fractionalPart = str_pad($this->fractionalPart, $scale, '0'); } } else { - $this->integralPart = bcmul($matches[2], bcpow('10', (string)$exp)); + /** @var numeric-string $matchValue */ + $matchValue = $matches[2]; + /** @var numeric-string $multiplier */ + $multiplier = bcpow('10', (string)$exp); + $this->integralPart = bcmul($matchValue, $multiplier); $pos = strlen((string)$this->integralPart); if (strpos($value, '.') !== false) {