← All changes
|
includes/sdk/google/brick/math/src/BigNumber.php
+134
-184
1.2.13
→
1.4.1
View file →
| @@ -1,25 +1,30 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | declare (strict_types=1); |
| 4 | -namespace Dudlewebs\WPMCS\Brick\Math; | |
| 4 | +namespace Dudlewebs\WPMCS\GCP\Brick\Math; | |
| 5 | 5 | |
| 6 | -use Dudlewebs\WPMCS\Brick\Math\Exception\DivisionByZeroException; | |
| 7 | -use Dudlewebs\WPMCS\Brick\Math\Exception\MathException; | |
| 8 | -use Dudlewebs\WPMCS\Brick\Math\Exception\NumberFormatException; | |
| 9 | -use Dudlewebs\WPMCS\Brick\Math\Exception\RoundingNecessaryException; | |
| 6 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\DivisionByZeroException; | |
| 7 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\MathException; | |
| 8 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\NumberFormatException; | |
| 9 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\RoundingNecessaryException; | |
| 10 | +use Dudlewebs\WPMCS\GCP\Override; | |
| 10 | 11 | /** |
| 11 | 12 | * Common interface for arbitrary-precision rational numbers. |
| 12 | 13 | * |
| 13 | 14 | * @psalm-immutable |
| 14 | 15 | */ |
| 15 | -abstract class BigNumber implements \Serializable, \JsonSerializable | |
| 16 | +abstract class BigNumber implements \JsonSerializable | |
| 16 | 17 | { |
| 17 | 18 | /** |
| 18 | - * The regular expression used to parse integer, decimal and rational numbers. | |
| 19 | + * The regular expression used to parse integer or decimal numbers. | |
| 19 | 20 | */ |
| 20 | - private const PARSE_REGEXP = '/^' . '(?<sign>[\-\+])?' . '(?:' . '(?:' . '(?<integral>[0-9]+)?' . '(?<point>\.)?' . '(?<fractional>[0-9]+)?' . '(?:[eE](?<exponent>[\-\+]?[0-9]+))?' . ')|(?:' . '(?<numerator>[0-9]+)' . '\/?' . '(?<denominator>[0-9]+)' . ')' . ')' . '$/'; | |
| 21 | + private const PARSE_REGEXP_NUMERICAL = '/^' . '(?<sign>[\\-\\+])?' . '(?<integral>[0-9]+)?' . '(?<point>\\.)?' . '(?<fractional>[0-9]+)?' . '(?:[eE](?<exponent>[\\-\\+]?[0-9]+))?' . '$/'; | |
| 21 | 22 | /** |
| 23 | + * The regular expression used to parse rational numbers. | |
| 24 | + */ | |
| 25 | + private const PARSE_REGEXP_RATIONAL = '/^' . '(?<sign>[\\-\\+])?' . '(?<numerator>[0-9]+)' . '\\/?' . '(?<denominator>[0-9]+)' . '$/'; | |
| 26 | + /** | |
| 22 | 27 | * Creates a BigNumber of the given value. |
| 23 | 28 | * |
| 24 | 29 | * The concrete return type is dependent on the given value, with the following rules: |
| 25 | 30 | * |
| @@ -29,18 +34,31 @@ | ||
| 29 | 34 | * - strings containing a `/` character are returned as BigRational |
| 30 | 35 | * - strings containing a `.` character or using an exponential notation are returned as BigDecimal |
| 31 | 36 | * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger |
| 32 | 37 | * |
| 33 | - * @param BigNumber|int|float|string $value | |
| 38 | + * @throws NumberFormatException If the format of the number is not valid. | |
| 39 | + * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. | |
| 40 | + * @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding. | |
| 34 | 41 | * |
| 35 | - * @return BigNumber | |
| 36 | - * | |
| 37 | - * @throws NumberFormatException If the format of the number is not valid. | |
| 42 | + * @psalm-pure | |
| 43 | + */ | |
| 44 | + public static final function of(BigNumber|int|float|string $value) : static | |
| 45 | + { | |
| 46 | + $value = self::_of($value); | |
| 47 | + if (static::class === BigNumber::class) { | |
| 48 | + // https://github.com/vimeo/psalm/issues/10309 | |
| 49 | + \assert($value instanceof static); | |
| 50 | + return $value; | |
| 51 | + } | |
| 52 | + return static::from($value); | |
| 53 | + } | |
| 54 | + /** | |
| 55 | + * @throws NumberFormatException If the format of the number is not valid. | |
| 38 | 56 | * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. |
| 39 | 57 | * |
| 40 | 58 | * @psalm-pure |
| 41 | 59 | */ |
| 42 | - public static function of($value): BigNumber | |
| 60 | + private static function _of(BigNumber|int|float|string $value) : BigNumber | |
| 43 | 61 | { |
| 44 | 62 | if ($value instanceof BigNumber) { |
| 45 | 63 | return $value; |
| 46 | 64 | } |
| @@ -46,99 +64,100 @@ | ||
| 46 | 64 | } |
| 47 | 65 | if (\is_int($value)) { |
| 48 | 66 | return new BigInteger((string) $value); |
| 49 | 67 | } |
| 50 | - /** @psalm-suppress RedundantCastGivenDocblockType We cannot trust the untyped $value here! */ | |
| 51 | - $value = \is_float($value) ? self::floatToString($value) : (string) $value; | |
| 52 | - $throw = static function () use ($value): void { | |
| 53 | - throw new NumberFormatException(\sprintf('The given value "%s" does not represent a valid number.', $value)); | |
| 54 | - }; | |
| 55 | - if (\preg_match(self::PARSE_REGEXP, $value, $matches) !== 1) { | |
| 56 | - $throw(); | |
| 68 | + if (\is_float($value)) { | |
| 69 | + $value = (string) $value; | |
| 57 | 70 | } |
| 58 | - $getMatch = static function (string $value) use ($matches): ?string { | |
| 59 | - return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null; | |
| 60 | - }; | |
| 61 | - $sign = $getMatch('sign'); | |
| 62 | - $numerator = $getMatch('numerator'); | |
| 63 | - $denominator = $getMatch('denominator'); | |
| 64 | - if ($numerator !== null) { | |
| 65 | - assert($denominator !== null); | |
| 66 | - if ($sign !== null) { | |
| 67 | - $numerator = $sign . $numerator; | |
| 71 | + if (\str_contains($value, '/')) { | |
| 72 | + // Rational number | |
| 73 | + if (\preg_match(self::PARSE_REGEXP_RATIONAL, $value, $matches, \PREG_UNMATCHED_AS_NULL) !== 1) { | |
| 74 | + throw NumberFormatException::invalidFormat($value); | |
| 68 | 75 | } |
| 69 | - $numerator = self::cleanUp($numerator); | |
| 70 | - $denominator = self::cleanUp($denominator); | |
| 76 | + $sign = $matches['sign']; | |
| 77 | + $numerator = $matches['numerator']; | |
| 78 | + $denominator = $matches['denominator']; | |
| 79 | + \assert($numerator !== null); | |
| 80 | + \assert($denominator !== null); | |
| 81 | + $numerator = self::cleanUp($sign, $numerator); | |
| 82 | + $denominator = self::cleanUp(null, $denominator); | |
| 71 | 83 | if ($denominator === '0') { |
| 72 | 84 | throw DivisionByZeroException::denominatorMustNotBeZero(); |
| 73 | 85 | } |
| 74 | 86 | return new BigRational(new BigInteger($numerator), new BigInteger($denominator), \false); |
| 75 | - } | |
| 76 | - $point = $getMatch('point'); | |
| 77 | - $integral = $getMatch('integral'); | |
| 78 | - $fractional = $getMatch('fractional'); | |
| 79 | - $exponent = $getMatch('exponent'); | |
| 80 | - if ($integral === null && $fractional === null) { | |
| 81 | - $throw(); | |
| 82 | - } | |
| 83 | - if ($integral === null) { | |
| 84 | - $integral = '0'; | |
| 85 | - } | |
| 86 | - if ($point !== null || $exponent !== null) { | |
| 87 | - $fractional = $fractional ?? ''; | |
| 88 | - $exponent = $exponent !== null ? (int) $exponent : 0; | |
| 89 | - if ($exponent === \PHP_INT_MIN || $exponent === \PHP_INT_MAX) { | |
| 90 | - throw new NumberFormatException('Exponent too large.'); | |
| 87 | + } else { | |
| 88 | + // Integer or decimal number | |
| 89 | + if (\preg_match(self::PARSE_REGEXP_NUMERICAL, $value, $matches, \PREG_UNMATCHED_AS_NULL) !== 1) { | |
| 90 | + throw NumberFormatException::invalidFormat($value); | |
| 91 | 91 | } |
| 92 | - $unscaledValue = self::cleanUp(($sign ?? '') . $integral . $fractional); | |
| 93 | - $scale = \strlen($fractional) - $exponent; | |
| 94 | - if ($scale < 0) { | |
| 95 | - if ($unscaledValue !== '0') { | |
| 96 | - $unscaledValue .= \str_repeat('0', -$scale); | |
| 92 | + $sign = $matches['sign']; | |
| 93 | + $point = $matches['point']; | |
| 94 | + $integral = $matches['integral']; | |
| 95 | + $fractional = $matches['fractional']; | |
| 96 | + $exponent = $matches['exponent']; | |
| 97 | + if ($integral === null && $fractional === null) { | |
| 98 | + throw NumberFormatException::invalidFormat($value); | |
| 99 | + } | |
| 100 | + if ($integral === null) { | |
| 101 | + $integral = '0'; | |
| 102 | + } | |
| 103 | + if ($point !== null || $exponent !== null) { | |
| 104 | + $fractional = $fractional ?? ''; | |
| 105 | + $exponent = $exponent !== null ? (int) $exponent : 0; | |
| 106 | + if ($exponent === \PHP_INT_MIN || $exponent === \PHP_INT_MAX) { | |
| 107 | + throw new NumberFormatException('Exponent too large.'); | |
| 97 | 108 | } |
| 98 | - $scale = 0; | |
| 109 | + $unscaledValue = self::cleanUp($sign, $integral . $fractional); | |
| 110 | + $scale = \strlen($fractional) - $exponent; | |
| 111 | + if ($scale < 0) { | |
| 112 | + if ($unscaledValue !== '0') { | |
| 113 | + $unscaledValue .= \str_repeat('0', -$scale); | |
| 114 | + } | |
| 115 | + $scale = 0; | |
| 116 | + } | |
| 117 | + return new BigDecimal($unscaledValue, $scale); | |
| 99 | 118 | } |
| 100 | - return new BigDecimal($unscaledValue, $scale); | |
| 119 | + $integral = self::cleanUp($sign, $integral); | |
| 120 | + return new BigInteger($integral); | |
| 101 | 121 | } |
| 102 | - $integral = self::cleanUp(($sign ?? '') . $integral); | |
| 103 | - return new BigInteger($integral); | |
| 104 | 122 | } |
| 105 | 123 | /** |
| 106 | - * Safely converts float to string, avoiding locale-dependent issues. | |
| 124 | + * Overridden by subclasses to convert a BigNumber to an instance of the subclass. | |
| 107 | 125 | * |
| 108 | - * @see https://github.com/brick/math/pull/20 | |
| 126 | + * @throws RoundingNecessaryException If the value cannot be converted. | |
| 109 | 127 | * |
| 110 | - * @param float $float | |
| 128 | + * @psalm-pure | |
| 129 | + */ | |
| 130 | + protected static abstract function from(BigNumber $number) : static; | |
| 131 | + /** | |
| 132 | + * Proxy method to access BigInteger's protected constructor from sibling classes. | |
| 111 | 133 | * |
| 112 | - * @return string | |
| 134 | + * @internal | |
| 135 | + * @psalm-pure | |
| 136 | + */ | |
| 137 | + protected final function newBigInteger(string $value) : BigInteger | |
| 138 | + { | |
| 139 | + return new BigInteger($value); | |
| 140 | + } | |
| 141 | + /** | |
| 142 | + * Proxy method to access BigDecimal's protected constructor from sibling classes. | |
| 113 | 143 | * |
| 144 | + * @internal | |
| 114 | 145 | * @psalm-pure |
| 115 | - * @psalm-suppress ImpureFunctionCall | |
| 116 | 146 | */ |
| 117 | - private static function floatToString(float $float): string | |
| 147 | + protected final function newBigDecimal(string $value, int $scale = 0) : BigDecimal | |
| 118 | 148 | { |
| 119 | - $currentLocale = \setlocale(\LC_NUMERIC, '0'); | |
| 120 | - \setlocale(\LC_NUMERIC, 'C'); | |
| 121 | - $result = (string) $float; | |
| 122 | - \setlocale(\LC_NUMERIC, $currentLocale); | |
| 123 | - return $result; | |
| 149 | + return new BigDecimal($value, $scale); | |
| 124 | 150 | } |
| 125 | 151 | /** |
| 126 | - * Proxy method to access protected constructors from sibling classes. | |
| 152 | + * Proxy method to access BigRational's protected constructor from sibling classes. | |
| 127 | 153 | * |
| 128 | 154 | * @internal |
| 129 | - * | |
| 130 | - * @param mixed ...$args The arguments to the constructor. | |
| 131 | - * | |
| 132 | - * @return static | |
| 133 | - * | |
| 134 | 155 | * @psalm-pure |
| 135 | - * @psalm-suppress TooManyArguments | |
| 136 | - * @psalm-suppress UnsafeInstantiation | |
| 137 | 156 | */ |
| 138 | - protected static function create(...$args): BigNumber | |
| 157 | + protected final function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational | |
| 139 | 158 | { |
| 140 | - return new static(...$args); | |
| 159 | + return new BigRational($numerator, $denominator, $checkDenominator); | |
| 141 | 160 | } |
| 142 | 161 | /** |
| 143 | 162 | * Returns the minimum of the given values. |
| 144 | 163 | * |
| @@ -144,18 +163,14 @@ | ||
| 144 | 163 | * |
| 145 | 164 | * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible |
| 146 | 165 | * to an instance of the class this method is called on. |
| 147 | 166 | * |
| 148 | - * @return static The minimum value. | |
| 149 | - * | |
| 150 | 167 | * @throws \InvalidArgumentException If no values are given. |
| 151 | 168 | * @throws MathException If an argument is not valid. |
| 152 | 169 | * |
| 153 | - * @psalm-suppress LessSpecificReturnStatement | |
| 154 | - * @psalm-suppress MoreSpecificReturnType | |
| 155 | 170 | * @psalm-pure |
| 156 | 171 | */ |
| 157 | - public static function min(...$values): BigNumber | |
| 172 | + public static final function min(BigNumber|int|float|string ...$values) : static | |
| 158 | 173 | { |
| 159 | 174 | $min = null; |
| 160 | 175 | foreach ($values as $value) { |
| 161 | 176 | $value = static::of($value); |
| @@ -173,18 +188,14 @@ | ||
| 173 | 188 | * |
| 174 | 189 | * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible |
| 175 | 190 | * to an instance of the class this method is called on. |
| 176 | 191 | * |
| 177 | - * @return static The maximum value. | |
| 178 | - * | |
| 179 | 192 | * @throws \InvalidArgumentException If no values are given. |
| 180 | 193 | * @throws MathException If an argument is not valid. |
| 181 | 194 | * |
| 182 | - * @psalm-suppress LessSpecificReturnStatement | |
| 183 | - * @psalm-suppress MoreSpecificReturnType | |
| 184 | 195 | * @psalm-pure |
| 185 | 196 | */ |
| 186 | - public static function max(...$values): BigNumber | |
| 197 | + public static final function max(BigNumber|int|float|string ...$values) : static | |
| 187 | 198 | { |
| 188 | 199 | $max = null; |
| 189 | 200 | foreach ($values as $value) { |
| 190 | 201 | $value = static::of($value); |
| @@ -202,20 +213,16 @@ | ||
| 202 | 213 | * |
| 203 | 214 | * @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible |
| 204 | 215 | * to an instance of the class this method is called on. |
| 205 | 216 | * |
| 206 | - * @return static The sum. | |
| 207 | - * | |
| 208 | 217 | * @throws \InvalidArgumentException If no values are given. |
| 209 | 218 | * @throws MathException If an argument is not valid. |
| 210 | 219 | * |
| 211 | - * @psalm-suppress LessSpecificReturnStatement | |
| 212 | - * @psalm-suppress MoreSpecificReturnType | |
| 213 | 220 | * @psalm-pure |
| 214 | 221 | */ |
| 215 | - public static function sum(...$values): BigNumber | |
| 222 | + public static final function sum(BigNumber|int|float|string ...$values) : static | |
| 216 | 223 | { |
| 217 | - /** @var BigNumber|null $sum */ | |
| 224 | + /** @var static|null $sum */ | |
| 218 | 225 | $sum = null; |
| 219 | 226 | foreach ($values as $value) { |
| 220 | 227 | $value = static::of($value); |
| 221 | 228 | $sum = $sum === null ? $value : self::add($sum, $value); |
| @@ -232,16 +239,11 @@ | ||
| 232 | 239 | * concrete classes the responsibility to perform the addition themselves or delegate it to the given number, |
| 233 | 240 | * depending on their ability to perform the operation. This will also require a version bump because we're |
| 234 | 241 | * potentially breaking custom BigNumber implementations (if any...) |
| 235 | 242 | * |
| 236 | - * @param BigNumber $a | |
| 237 | - * @param BigNumber $b | |
| 238 | - * | |
| 239 | - * @return BigNumber | |
| 240 | - * | |
| 241 | 243 | * @psalm-pure |
| 242 | 244 | */ |
| 243 | - private static function add(BigNumber $a, BigNumber $b): BigNumber | |
| 245 | + private static function add(BigNumber $a, BigNumber $b) : BigNumber | |
| 244 | 246 | { |
| 245 | 247 | if ($a instanceof BigRational) { |
| 246 | 248 | return $a->plus($b); |
| 247 | 249 | } |
| @@ -257,128 +259,90 @@ | ||
| 257 | 259 | /** @var BigInteger $a */ |
| 258 | 260 | return $a->plus($b); |
| 259 | 261 | } |
| 260 | 262 | /** |
| 261 | - * Removes optional leading zeros and + sign from the given number. | |
| 263 | + * Removes optional leading zeros and applies sign. | |
| 262 | 264 | * |
| 263 | - * @param string $number The number, validated as a non-empty string of digits with optional leading sign. | |
| 265 | + * @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'. | |
| 266 | + * @param string $number The number, validated as a non-empty string of digits. | |
| 264 | 267 | * |
| 265 | - * @return string | |
| 266 | - * | |
| 267 | 268 | * @psalm-pure |
| 268 | 269 | */ |
| 269 | - private static function cleanUp(string $number): string | |
| 270 | + private static function cleanUp(string|null $sign, string $number) : string | |
| 270 | 271 | { |
| 271 | - $firstChar = $number[0]; | |
| 272 | - if ($firstChar === '+' || $firstChar === '-') { | |
| 273 | - $number = \substr($number, 1); | |
| 274 | - } | |
| 275 | 272 | $number = \ltrim($number, '0'); |
| 276 | 273 | if ($number === '') { |
| 277 | 274 | return '0'; |
| 278 | 275 | } |
| 279 | - if ($firstChar === '-') { | |
| 280 | - return '-' . $number; | |
| 281 | - } | |
| 282 | - return $number; | |
| 276 | + return $sign === '-' ? '-' . $number : $number; | |
| 283 | 277 | } |
| 284 | 278 | /** |
| 285 | 279 | * Checks if this number is equal to the given one. |
| 286 | - * | |
| 287 | - * @param BigNumber|int|float|string $that | |
| 288 | - * | |
| 289 | - * @return bool | |
| 290 | 280 | */ |
| 291 | - public function isEqualTo($that): bool | |
| 281 | + public final function isEqualTo(BigNumber|int|float|string $that) : bool | |
| 292 | 282 | { |
| 293 | 283 | return $this->compareTo($that) === 0; |
| 294 | 284 | } |
| 295 | 285 | /** |
| 296 | 286 | * Checks if this number is strictly lower than the given one. |
| 297 | - * | |
| 298 | - * @param BigNumber|int|float|string $that | |
| 299 | - * | |
| 300 | - * @return bool | |
| 301 | 287 | */ |
| 302 | - public function isLessThan($that): bool | |
| 288 | + public final function isLessThan(BigNumber|int|float|string $that) : bool | |
| 303 | 289 | { |
| 304 | 290 | return $this->compareTo($that) < 0; |
| 305 | 291 | } |
| 306 | 292 | /** |
| 307 | 293 | * Checks if this number is lower than or equal to the given one. |
| 308 | - * | |
| 309 | - * @param BigNumber|int|float|string $that | |
| 310 | - * | |
| 311 | - * @return bool | |
| 312 | 294 | */ |
| 313 | - public function isLessThanOrEqualTo($that): bool | |
| 295 | + public final function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool | |
| 314 | 296 | { |
| 315 | 297 | return $this->compareTo($that) <= 0; |
| 316 | 298 | } |
| 317 | 299 | /** |
| 318 | 300 | * Checks if this number is strictly greater than the given one. |
| 319 | - * | |
| 320 | - * @param BigNumber|int|float|string $that | |
| 321 | - * | |
| 322 | - * @return bool | |
| 323 | 301 | */ |
| 324 | - public function isGreaterThan($that): bool | |
| 302 | + public final function isGreaterThan(BigNumber|int|float|string $that) : bool | |
| 325 | 303 | { |
| 326 | 304 | return $this->compareTo($that) > 0; |
| 327 | 305 | } |
| 328 | 306 | /** |
| 329 | 307 | * Checks if this number is greater than or equal to the given one. |
| 330 | - * | |
| 331 | - * @param BigNumber|int|float|string $that | |
| 332 | - * | |
| 333 | - * @return bool | |
| 334 | 308 | */ |
| 335 | - public function isGreaterThanOrEqualTo($that): bool | |
| 309 | + public final function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool | |
| 336 | 310 | { |
| 337 | 311 | return $this->compareTo($that) >= 0; |
| 338 | 312 | } |
| 339 | 313 | /** |
| 340 | 314 | * Checks if this number equals zero. |
| 341 | - * | |
| 342 | - * @return bool | |
| 343 | 315 | */ |
| 344 | - public function isZero(): bool | |
| 316 | + public final function isZero() : bool | |
| 345 | 317 | { |
| 346 | 318 | return $this->getSign() === 0; |
| 347 | 319 | } |
| 348 | 320 | /** |
| 349 | 321 | * Checks if this number is strictly negative. |
| 350 | - * | |
| 351 | - * @return bool | |
| 352 | 322 | */ |
| 353 | - public function isNegative(): bool | |
| 323 | + public final function isNegative() : bool | |
| 354 | 324 | { |
| 355 | 325 | return $this->getSign() < 0; |
| 356 | 326 | } |
| 357 | 327 | /** |
| 358 | 328 | * Checks if this number is negative or zero. |
| 359 | - * | |
| 360 | - * @return bool | |
| 361 | 329 | */ |
| 362 | - public function isNegativeOrZero(): bool | |
| 330 | + public final function isNegativeOrZero() : bool | |
| 363 | 331 | { |
| 364 | 332 | return $this->getSign() <= 0; |
| 365 | 333 | } |
| 366 | 334 | /** |
| 367 | 335 | * Checks if this number is strictly positive. |
| 368 | - * | |
| 369 | - * @return bool | |
| 370 | 336 | */ |
| 371 | - public function isPositive(): bool | |
| 337 | + public final function isPositive() : bool | |
| 372 | 338 | { |
| 373 | 339 | return $this->getSign() > 0; |
| 374 | 340 | } |
| 375 | 341 | /** |
| 376 | 342 | * Checks if this number is positive or zero. |
| 377 | - * | |
| 378 | - * @return bool | |
| 379 | 343 | */ |
| 380 | - public function isPositiveOrZero(): bool | |
| 344 | + public final function isPositiveOrZero() : bool | |
| 381 | 345 | { |
| 382 | 346 | return $this->getSign() >= 0; |
| 383 | 347 | } |
| 384 | 348 | /** |
| @@ -383,55 +347,49 @@ | ||
| 383 | 347 | } |
| 384 | 348 | /** |
| 385 | 349 | * Returns the sign of this number. |
| 386 | 350 | * |
| 351 | + * @psalm-return -1|0|1 | |
| 352 | + * | |
| 387 | 353 | * @return int -1 if the number is negative, 0 if zero, 1 if positive. |
| 388 | 354 | */ |
| 389 | - abstract public function getSign(): int; | |
| 355 | + public abstract function getSign() : int; | |
| 390 | 356 | /** |
| 391 | 357 | * Compares this number to the given one. |
| 392 | 358 | * |
| 393 | - * @param BigNumber|int|float|string $that | |
| 359 | + * @psalm-return -1|0|1 | |
| 394 | 360 | * |
| 395 | - * @return int [-1,0,1] If `$this` is lower than, equal to, or greater than `$that`. | |
| 361 | + * @return int -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`. | |
| 396 | 362 | * |
| 397 | 363 | * @throws MathException If the number is not valid. |
| 398 | 364 | */ |
| 399 | - abstract public function compareTo($that): int; | |
| 365 | + public abstract function compareTo(BigNumber|int|float|string $that) : int; | |
| 400 | 366 | /** |
| 401 | 367 | * Converts this number to a BigInteger. |
| 402 | 368 | * |
| 403 | - * @return BigInteger The converted number. | |
| 404 | - * | |
| 405 | 369 | * @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding. |
| 406 | 370 | */ |
| 407 | - abstract public function toBigInteger(): BigInteger; | |
| 371 | + public abstract function toBigInteger() : BigInteger; | |
| 408 | 372 | /** |
| 409 | 373 | * Converts this number to a BigDecimal. |
| 410 | 374 | * |
| 411 | - * @return BigDecimal The converted number. | |
| 412 | - * | |
| 413 | 375 | * @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding. |
| 414 | 376 | */ |
| 415 | - abstract public function toBigDecimal(): BigDecimal; | |
| 377 | + public abstract function toBigDecimal() : BigDecimal; | |
| 416 | 378 | /** |
| 417 | 379 | * Converts this number to a BigRational. |
| 418 | - * | |
| 419 | - * @return BigRational The converted number. | |
| 420 | 380 | */ |
| 421 | - abstract public function toBigRational(): BigRational; | |
| 381 | + public abstract function toBigRational() : BigRational; | |
| 422 | 382 | /** |
| 423 | 383 | * Converts this number to a BigDecimal with the given scale, using rounding if necessary. |
| 424 | 384 | * |
| 425 | - * @param int $scale The scale of the resulting `BigDecimal`. | |
| 426 | - * @param int $roundingMode A `RoundingMode` constant. | |
| 385 | + * @param int $scale The scale of the resulting `BigDecimal`. | |
| 386 | + * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. | |
| 427 | 387 | * |
| 428 | - * @return BigDecimal | |
| 429 | - * | |
| 430 | 388 | * @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding. |
| 431 | 389 | * This only applies when RoundingMode::UNNECESSARY is used. |
| 432 | 390 | */ |
| 433 | - abstract public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY): BigDecimal; | |
| 391 | + public abstract function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; | |
| 434 | 392 | /** |
| 435 | 393 | * Returns the exact value of this number as a native integer. |
| 436 | 394 | * |
| 437 | 395 | * If this number cannot be converted to a native integer without losing precision, an exception is thrown. |
| @@ -436,13 +394,11 @@ | ||
| 436 | 394 | * |
| 437 | 395 | * If this number cannot be converted to a native integer without losing precision, an exception is thrown. |
| 438 | 396 | * Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit. |
| 439 | 397 | * |
| 440 | - * @return int The converted value. | |
| 441 | - * | |
| 442 | 398 | * @throws MathException If this number cannot be exactly converted to a native integer. |
| 443 | 399 | */ |
| 444 | - abstract public function toInt(): int; | |
| 400 | + public abstract function toInt() : int; | |
| 445 | 401 | /** |
| 446 | 402 | * Returns an approximation of this number as a floating-point value. |
| 447 | 403 | * |
| 448 | 404 | * Note that this method can discard information as the precision of a floating-point value |
| @@ -449,25 +405,19 @@ | ||
| 449 | 405 | * is inherently limited. |
| 450 | 406 | * |
| 451 | 407 | * If the number is greater than the largest representable floating point number, positive infinity is returned. |
| 452 | 408 | * If the number is less than the smallest representable floating point number, negative infinity is returned. |
| 453 | - * | |
| 454 | - * @return float The converted value. | |
| 455 | 409 | */ |
| 456 | - abstract public function toFloat(): float; | |
| 410 | + public abstract function toFloat() : float; | |
| 457 | 411 | /** |
| 458 | 412 | * Returns a string representation of this number. |
| 459 | 413 | * |
| 460 | 414 | * The output of this method can be parsed by the `of()` factory method; |
| 461 | 415 | * this will yield an object equal to this one, without any information loss. |
| 462 | - * | |
| 463 | - * @return string | |
| 464 | 416 | */ |
| 465 | - abstract public function __toString(): string; | |
| 466 | - /** | |
| 467 | - * {@inheritdoc} | |
| 468 | - */ | |
| 469 | - public function jsonSerialize(): string | |
| 417 | + public abstract function __toString() : string; | |
| 418 | + #[\Override] | |
| 419 | + public final function jsonSerialize() : string | |
| 470 | 420 | { |
| 471 | 421 | return $this->__toString(); |
| 472 | 422 | } |
| 473 | 423 | } |