aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/brick/math/src/BigDecimal.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/brick/math/src/BigDecimal.php')
-rw-r--r--vendor/brick/math/src/BigDecimal.php92
1 files changed, 49 insertions, 43 deletions
diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php
index 02fc65612..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.
@@ -23,14 +24,14 @@ final class BigDecimal extends BigNumber
* No leading zero must be present.
* No leading minus sign must be present if the value is 0.
*/
- private string $value;
+ private readonly string $value;
/**
* The scale (number of digits after the decimal point) of this decimal number.
*
* This must be zero or more.
*/
- private int $scale;
+ private readonly int $scale;
/**
* Protected constructor. Use a factory method to obtain an instance.
@@ -45,15 +46,12 @@ final class BigDecimal extends BigNumber
}
/**
- * Creates a BigDecimal of the given value.
- *
- * @throws MathException If the value cannot be converted to a BigDecimal.
- *
* @psalm-pure
*/
- public static function of(BigNumber|int|float|string $value) : BigDecimal
+ #[Override]
+ protected static function from(BigNumber $number): static
{
- return parent::of($value)->toBigDecimal();
+ return $number->toBigDecimal();
}
/**
@@ -223,12 +221,12 @@ final class BigDecimal extends BigNumber
*
* @param BigNumber|int|float|string $that The divisor.
* @param int|null $scale The desired scale, or null to use the scale of this number.
- * @param int $roundingMode An optional rounding mode.
+ * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY.
*
* @throws \InvalidArgumentException If the scale or rounding mode is invalid.
* @throws MathException If the number is invalid, is zero, or rounding was necessary.
*/
- public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
+ public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
{
$that = BigDecimal::of($that);
@@ -324,7 +322,7 @@ final class BigDecimal extends BigNumber
}
/**
- * Returns the quotient of the division of this number by this given one.
+ * Returns the quotient of the division of this number by the given one.
*
* The quotient has a scale of `0`.
*
@@ -349,7 +347,7 @@ final class BigDecimal extends BigNumber
}
/**
- * Returns the remainder of the division of this number by this given one.
+ * Returns the remainder of the division of this number by the given one.
*
* The remainder has a scale of `max($this->scale, $that->scale)`.
*
@@ -384,6 +382,8 @@ final class BigDecimal extends BigNumber
*
* @return BigDecimal[] An array containing the quotient and the remainder.
*
+ * @psalm-return array{BigDecimal, BigDecimal}
+ *
* @throws MathException If the divisor is not a valid decimal number, or is zero.
*/
public function quotientAndRemainder(BigNumber|int|float|string $that) : array
@@ -537,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);
@@ -554,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);
@@ -570,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`.
@@ -611,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);
@@ -618,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);
@@ -631,7 +663,8 @@ final class BigDecimal extends BigNumber
return self::newBigRational($numerator, $denominator, false);
}
- public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
+ #[Override]
+ public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
{
if ($scale === $this->scale) {
return $this;
@@ -640,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) {
@@ -694,36 +730,6 @@ final class BigDecimal extends BigNumber
}
/**
- * This method is required by interface Serializable and SHOULD NOT be accessed directly.
- *
- * @internal
- */
- public function serialize() : string
- {
- return $this->value . ':' . $this->scale;
- }
-
- /**
- * This method is only here to implement interface Serializable and cannot be accessed directly.
- *
- * @internal
- * @psalm-suppress RedundantPropertyInitializationCheck
- *
- * @throws \LogicException
- */
- public function unserialize($value) : void
- {
- if (isset($this->value)) {
- throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
- }
-
- [$value, $scale] = \explode(':', $value);
-
- $this->value = $value;
- $this->scale = (int) $scale;
- }
-
- /**
* Puts the internal values of the given decimal numbers on the same scale.
*
* @return array{string, string} The scaled integer values of $x and $y.