← All changes
|
includes/sdk/google/brick/math/src/BigInteger.php
+95
-215
1.2.9
→
1.4.1
View file →
| @@ -1,15 +1,16 @@ | ||
| 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\IntegerOverflowException; | |
| 8 | -use Dudlewebs\WPMCS\Brick\Math\Exception\MathException; | |
| 9 | -use Dudlewebs\WPMCS\Brick\Math\Exception\NegativeNumberException; | |
| 10 | -use Dudlewebs\WPMCS\Brick\Math\Exception\NumberFormatException; | |
| 11 | -use Dudlewebs\WPMCS\Brick\Math\Internal\Calculator; | |
| 6 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\DivisionByZeroException; | |
| 7 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\IntegerOverflowException; | |
| 8 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\MathException; | |
| 9 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\NegativeNumberException; | |
| 10 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Exception\NumberFormatException; | |
| 11 | +use Dudlewebs\WPMCS\GCP\Brick\Math\Internal\Calculator; | |
| 12 | +use Dudlewebs\WPMCS\GCP\Override; | |
| 12 | 13 | /** |
| 13 | 14 | * An arbitrary-size integer. |
| 14 | 15 | * |
| 15 | 16 | * All methods accepting a number as a parameter accept either a BigInteger instance, |
| @@ -23,12 +24,10 @@ | ||
| 23 | 24 | * The value, as a string of digits with optional leading minus sign. |
| 24 | 25 | * |
| 25 | 26 | * No leading zeros must be present. |
| 26 | 27 | * No leading minus sign must be present if the number is zero. |
| 27 | - * | |
| 28 | - * @var string | |
| 29 | 28 | */ |
| 30 | - private $value; | |
| 29 | + private readonly string $value; | |
| 31 | 30 | /** |
| 32 | 31 | * Protected constructor. Use a factory method to obtain an instance. |
| 33 | 32 | * |
| 34 | 33 | * @param string $value A string of digits, with optional leading minus sign. |
| @@ -37,21 +36,14 @@ | ||
| 37 | 36 | { |
| 38 | 37 | $this->value = $value; |
| 39 | 38 | } |
| 40 | 39 | /** |
| 41 | - * Creates a BigInteger of the given value. | |
| 42 | - * | |
| 43 | - * @param BigNumber|int|float|string $value | |
| 44 | - * | |
| 45 | - * @return BigInteger | |
| 46 | - * | |
| 47 | - * @throws MathException If the value cannot be converted to a BigInteger. | |
| 48 | - * | |
| 49 | 40 | * @psalm-pure |
| 50 | 41 | */ |
| 51 | - public static function of($value): BigNumber | |
| 42 | + #[\Override] | |
| 43 | + protected static function from(BigNumber $number) : static | |
| 52 | 44 | { |
| 53 | - return parent::of($value)->toBigInteger(); | |
| 45 | + return $number->toBigInteger(); | |
| 54 | 46 | } |
| 55 | 47 | /** |
| 56 | 48 | * Creates a number from a string in a given base. |
| 57 | 49 | * |
| @@ -65,16 +57,14 @@ | ||
| 65 | 57 | * |
| 66 | 58 | * @param string $number The number to convert, in the given base. |
| 67 | 59 | * @param int $base The base of the number, between 2 and 36. |
| 68 | 60 | * |
| 69 | - * @return BigInteger | |
| 70 | - * | |
| 71 | 61 | * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. |
| 72 | 62 | * @throws \InvalidArgumentException If the base is out of range. |
| 73 | 63 | * |
| 74 | 64 | * @psalm-pure |
| 75 | 65 | */ |
| 76 | - public static function fromBase(string $number, int $base): BigInteger | |
| 66 | + public static function fromBase(string $number, int $base) : BigInteger | |
| 77 | 67 | { |
| 78 | 68 | if ($number === '') { |
| 79 | 69 | throw new NumberFormatException('The number cannot be empty.'); |
| 80 | 70 | } |
| @@ -120,16 +110,14 @@ | ||
| 120 | 110 | * |
| 121 | 111 | * @param string $number The number to parse. |
| 122 | 112 | * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. |
| 123 | 113 | * |
| 124 | - * @return BigInteger | |
| 125 | - * | |
| 126 | 114 | * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. |
| 127 | 115 | * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. |
| 128 | 116 | * |
| 129 | 117 | * @psalm-pure |
| 130 | 118 | */ |
| 131 | - public static function fromArbitraryBase(string $number, string $alphabet): BigInteger | |
| 119 | + public static function fromArbitraryBase(string $number, string $alphabet) : BigInteger | |
| 132 | 120 | { |
| 133 | 121 | if ($number === '') { |
| 134 | 122 | throw new NumberFormatException('The number cannot be empty.'); |
| 135 | 123 | } |
| @@ -158,13 +146,11 @@ | ||
| 158 | 146 | * @param string $value The byte string. |
| 159 | 147 | * @param bool $signed Whether to interpret as a signed number in two's-complement representation with a leading |
| 160 | 148 | * sign bit. |
| 161 | 149 | * |
| 162 | - * @return BigInteger | |
| 163 | - * | |
| 164 | 150 | * @throws NumberFormatException If the string is empty. |
| 165 | 151 | */ |
| 166 | - public static function fromBytes(string $value, bool $signed = \true): BigInteger | |
| 152 | + public static function fromBytes(string $value, bool $signed = \true) : BigInteger | |
| 167 | 153 | { |
| 168 | 154 | if ($value === '') { |
| 169 | 155 | throw new NumberFormatException('The byte string must not be empty.'); |
| 170 | 156 | } |
| @@ -185,9 +171,9 @@ | ||
| 185 | 171 | * Generates a pseudo-random number in the range 0 to 2^numBits - 1. |
| 186 | 172 | * |
| 187 | 173 | * Using the default random bytes generator, this method is suitable for cryptographic use. |
| 188 | 174 | * |
| 189 | - * @psalm-param callable(int): string $randomBytesGenerator | |
| 175 | + * @psalm-param (callable(int): string)|null $randomBytesGenerator | |
| 190 | 176 | * |
| 191 | 177 | * @param int $numBits The number of bits. |
| 192 | 178 | * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a |
| 193 | 179 | * string of random bytes of the given length. Defaults to the |
| @@ -192,13 +178,11 @@ | ||
| 192 | 178 | * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a |
| 193 | 179 | * string of random bytes of the given length. Defaults to the |
| 194 | 180 | * `random_bytes()` function. |
| 195 | 181 | * |
| 196 | - * @return BigInteger | |
| 197 | - * | |
| 198 | 182 | * @throws \InvalidArgumentException If $numBits is negative. |
| 199 | 183 | */ |
| 200 | - public static function randomBits(int $numBits, ?callable $randomBytesGenerator = null): BigInteger | |
| 184 | + public static function randomBits(int $numBits, ?callable $randomBytesGenerator = null) : BigInteger | |
| 201 | 185 | { |
| 202 | 186 | if ($numBits < 0) { |
| 203 | 187 | throw new \InvalidArgumentException('The number of bits cannot be negative.'); |
| 204 | 188 | } |
| @@ -205,10 +189,11 @@ | ||
| 205 | 189 | if ($numBits === 0) { |
| 206 | 190 | return BigInteger::zero(); |
| 207 | 191 | } |
| 208 | 192 | if ($randomBytesGenerator === null) { |
| 209 | - $randomBytesGenerator = 'random_bytes'; | |
| 193 | + $randomBytesGenerator = \random_bytes(...); | |
| 210 | 194 | } |
| 195 | + /** @var int<1, max> $byteLength */ | |
| 211 | 196 | $byteLength = \intdiv($numBits - 1, 8) + 1; |
| 212 | 197 | $extraBits = $byteLength * 8 - $numBits; |
| 213 | 198 | $bitmask = \chr(0xff >> $extraBits); |
| 214 | 199 | $randomBytes = $randomBytesGenerator($byteLength); |
| @@ -227,14 +212,12 @@ | ||
| 227 | 212 | * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, |
| 228 | 213 | * and returns a string of random bytes of the given length. |
| 229 | 214 | * Defaults to the `random_bytes()` function. |
| 230 | 215 | * |
| 231 | - * @return BigInteger | |
| 232 | - * | |
| 233 | 216 | * @throws MathException If one of the parameters cannot be converted to a BigInteger, |
| 234 | 217 | * or `$min` is greater than `$max`. |
| 235 | 218 | */ |
| 236 | - public static function randomRange($min, $max, ?callable $randomBytesGenerator = null): BigInteger | |
| 219 | + public static function randomRange(BigNumber|int|float|string $min, BigNumber|int|float|string $max, ?callable $randomBytesGenerator = null) : BigInteger | |
| 237 | 220 | { |
| 238 | 221 | $min = BigInteger::of($min); |
| 239 | 222 | $max = BigInteger::of($max); |
| 240 | 223 | if ($min->isGreaterThan($max)) { |
| @@ -253,13 +236,11 @@ | ||
| 253 | 236 | } |
| 254 | 237 | /** |
| 255 | 238 | * Returns a BigInteger representing zero. |
| 256 | 239 | * |
| 257 | - * @return BigInteger | |
| 258 | - * | |
| 259 | 240 | * @psalm-pure |
| 260 | 241 | */ |
| 261 | - public static function zero(): BigInteger | |
| 242 | + public static function zero() : BigInteger | |
| 262 | 243 | { |
| 263 | 244 | /** |
| 264 | 245 | * @psalm-suppress ImpureStaticVariable |
| 265 | 246 | * @var BigInteger|null $zero |
| @@ -272,13 +253,11 @@ | ||
| 272 | 253 | } |
| 273 | 254 | /** |
| 274 | 255 | * Returns a BigInteger representing one. |
| 275 | 256 | * |
| 276 | - * @return BigInteger | |
| 277 | - * | |
| 278 | 257 | * @psalm-pure |
| 279 | 258 | */ |
| 280 | - public static function one(): BigInteger | |
| 259 | + public static function one() : BigInteger | |
| 281 | 260 | { |
| 282 | 261 | /** |
| 283 | 262 | * @psalm-suppress ImpureStaticVariable |
| 284 | 263 | * @var BigInteger|null $one |
| @@ -291,13 +270,11 @@ | ||
| 291 | 270 | } |
| 292 | 271 | /** |
| 293 | 272 | * Returns a BigInteger representing ten. |
| 294 | 273 | * |
| 295 | - * @return BigInteger | |
| 296 | - * | |
| 297 | 274 | * @psalm-pure |
| 298 | 275 | */ |
| 299 | - public static function ten(): BigInteger | |
| 276 | + public static function ten() : BigInteger | |
| 300 | 277 | { |
| 301 | 278 | /** |
| 302 | 279 | * @psalm-suppress ImpureStaticVariable |
| 303 | 280 | * @var BigInteger|null $ten |
| @@ -307,18 +284,27 @@ | ||
| 307 | 284 | $ten = new BigInteger('10'); |
| 308 | 285 | } |
| 309 | 286 | return $ten; |
| 310 | 287 | } |
| 288 | + public static function gcdMultiple(BigInteger $a, BigInteger ...$n) : BigInteger | |
| 289 | + { | |
| 290 | + $result = $a; | |
| 291 | + foreach ($n as $next) { | |
| 292 | + $result = $result->gcd($next); | |
| 293 | + if ($result->isEqualTo(1)) { | |
| 294 | + return $result; | |
| 295 | + } | |
| 296 | + } | |
| 297 | + return $result; | |
| 298 | + } | |
| 311 | 299 | /** |
| 312 | 300 | * Returns the sum of this number and the given one. |
| 313 | 301 | * |
| 314 | 302 | * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigInteger. |
| 315 | 303 | * |
| 316 | - * @return BigInteger The result. | |
| 317 | - * | |
| 318 | 304 | * @throws MathException If the number is not valid, or is not convertible to a BigInteger. |
| 319 | 305 | */ |
| 320 | - public function plus($that): BigInteger | |
| 306 | + public function plus(BigNumber|int|float|string $that) : BigInteger | |
| 321 | 307 | { |
| 322 | 308 | $that = BigInteger::of($that); |
| 323 | 309 | if ($that->value === '0') { |
| 324 | 310 | return $this; |
| @@ -333,13 +319,11 @@ | ||
| 333 | 319 | * Returns the difference of this number and the given one. |
| 334 | 320 | * |
| 335 | 321 | * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigInteger. |
| 336 | 322 | * |
| 337 | - * @return BigInteger The result. | |
| 338 | - * | |
| 339 | 323 | * @throws MathException If the number is not valid, or is not convertible to a BigInteger. |
| 340 | 324 | */ |
| 341 | - public function minus($that): BigInteger | |
| 325 | + public function minus(BigNumber|int|float|string $that) : BigInteger | |
| 342 | 326 | { |
| 343 | 327 | $that = BigInteger::of($that); |
| 344 | 328 | if ($that->value === '0') { |
| 345 | 329 | return $this; |
| @@ -351,13 +335,11 @@ | ||
| 351 | 335 | * Returns the product of this number and the given one. |
| 352 | 336 | * |
| 353 | 337 | * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigInteger. |
| 354 | 338 | * |
| 355 | - * @return BigInteger The result. | |
| 356 | - * | |
| 357 | 339 | * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigInteger. |
| 358 | 340 | */ |
| 359 | - public function multipliedBy($that): BigInteger | |
| 341 | + public function multipliedBy(BigNumber|int|float|string $that) : BigInteger | |
| 360 | 342 | { |
| 361 | 343 | $that = BigInteger::of($that); |
| 362 | 344 | if ($that->value === '1') { |
| 363 | 345 | return $this; |
| @@ -371,16 +353,14 @@ | ||
| 371 | 353 | /** |
| 372 | 354 | * Returns the result of the division of this number by the given one. |
| 373 | 355 | * |
| 374 | 356 | * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. |
| 375 | - * @param int $roundingMode An optional rounding mode. | |
| 357 | + * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. | |
| 376 | 358 | * |
| 377 | - * @return BigInteger The result. | |
| 378 | - * | |
| 379 | 359 | * @throws MathException If the divisor is not a valid number, is not convertible to a BigInteger, is zero, |
| 380 | 360 | * or RoundingMode::UNNECESSARY is used and the remainder is not zero. |
| 381 | 361 | */ |
| 382 | - public function dividedBy($that, int $roundingMode = RoundingMode::UNNECESSARY): BigInteger | |
| 362 | + public function dividedBy(BigNumber|int|float|string $that, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigInteger | |
| 383 | 363 | { |
| 384 | 364 | $that = BigInteger::of($that); |
| 385 | 365 | if ($that->value === '1') { |
| 386 | 366 | return $this; |
| @@ -393,15 +373,11 @@ | ||
| 393 | 373 | } |
| 394 | 374 | /** |
| 395 | 375 | * Returns this number exponentiated to the given value. |
| 396 | 376 | * |
| 397 | - * @param int $exponent The exponent. | |
| 398 | - * | |
| 399 | - * @return BigInteger The result. | |
| 400 | - * | |
| 401 | 377 | * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. |
| 402 | 378 | */ |
| 403 | - public function power(int $exponent): BigInteger | |
| 379 | + public function power(int $exponent) : BigInteger | |
| 404 | 380 | { |
| 405 | 381 | if ($exponent === 0) { |
| 406 | 382 | return BigInteger::one(); |
| 407 | 383 | } |
| @@ -417,13 +393,11 @@ | ||
| 417 | 393 | * Returns the quotient of the division of this number by the given one. |
| 418 | 394 | * |
| 419 | 395 | * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. |
| 420 | 396 | * |
| 421 | - * @return BigInteger | |
| 422 | - * | |
| 423 | 397 | * @throws DivisionByZeroException If the divisor is zero. |
| 424 | 398 | */ |
| 425 | - public function quotient($that): BigInteger | |
| 399 | + public function quotient(BigNumber|int|float|string $that) : BigInteger | |
| 426 | 400 | { |
| 427 | 401 | $that = BigInteger::of($that); |
| 428 | 402 | if ($that->value === '1') { |
| 429 | 403 | return $this; |
| @@ -440,13 +414,11 @@ | ||
| 440 | 414 | * The remainder, when non-zero, has the same sign as the dividend. |
| 441 | 415 | * |
| 442 | 416 | * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. |
| 443 | 417 | * |
| 444 | - * @return BigInteger | |
| 445 | - * | |
| 446 | 418 | * @throws DivisionByZeroException If the divisor is zero. |
| 447 | 419 | */ |
| 448 | - public function remainder($that): BigInteger | |
| 420 | + public function remainder(BigNumber|int|float|string $that) : BigInteger | |
| 449 | 421 | { |
| 450 | 422 | $that = BigInteger::of($that); |
| 451 | 423 | if ($that->value === '1') { |
| 452 | 424 | return BigInteger::zero(); |
| @@ -463,11 +435,13 @@ | ||
| 463 | 435 | * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. |
| 464 | 436 | * |
| 465 | 437 | * @return BigInteger[] An array containing the quotient and the remainder. |
| 466 | 438 | * |
| 439 | + * @psalm-return array{BigInteger, BigInteger} | |
| 440 | + * | |
| 467 | 441 | * @throws DivisionByZeroException If the divisor is zero. |
| 468 | 442 | */ |
| 469 | - public function quotientAndRemainder($that): array | |
| 443 | + public function quotientAndRemainder(BigNumber|int|float|string $that) : array | |
| 470 | 444 | { |
| 471 | 445 | $that = BigInteger::of($that); |
| 472 | 446 | if ($that->value === '0') { |
| 473 | 447 | throw DivisionByZeroException::divisionByZero(); |
| @@ -484,13 +458,11 @@ | ||
| 484 | 458 | * The result of the modulo operation, when non-zero, has the same sign as the divisor. |
| 485 | 459 | * |
| 486 | 460 | * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. |
| 487 | 461 | * |
| 488 | - * @return BigInteger | |
| 489 | - * | |
| 490 | 462 | * @throws DivisionByZeroException If the divisor is zero. |
| 491 | 463 | */ |
| 492 | - public function mod($that): BigInteger | |
| 464 | + public function mod(BigNumber|int|float|string $that) : BigInteger | |
| 493 | 465 | { |
| 494 | 466 | $that = BigInteger::of($that); |
| 495 | 467 | if ($that->value === '0') { |
| 496 | 468 | throw DivisionByZeroException::modulusMustNotBeZero(); |
| @@ -500,18 +472,14 @@ | ||
| 500 | 472 | } |
| 501 | 473 | /** |
| 502 | 474 | * Returns the modular multiplicative inverse of this BigInteger modulo $m. |
| 503 | 475 | * |
| 504 | - * @param BigInteger $m | |
| 505 | - * | |
| 506 | - * @return BigInteger | |
| 507 | - * | |
| 508 | 476 | * @throws DivisionByZeroException If $m is zero. |
| 509 | 477 | * @throws NegativeNumberException If $m is negative. |
| 510 | 478 | * @throws MathException If this BigInteger has no multiplicative inverse mod m (that is, this BigInteger |
| 511 | 479 | * is not relatively prime to m). |
| 512 | 480 | */ |
| 513 | - public function modInverse(BigInteger $m): BigInteger | |
| 481 | + public function modInverse(BigInteger $m) : BigInteger | |
| 514 | 482 | { |
| 515 | 483 | if ($m->value === '0') { |
| 516 | 484 | throw DivisionByZeroException::modulusMustNotBeZero(); |
| 517 | 485 | } |
| @@ -534,14 +502,12 @@ | ||
| 534 | 502 | * |
| 535 | 503 | * @param BigNumber|int|float|string $exp The exponent. Must be positive or zero. |
| 536 | 504 | * @param BigNumber|int|float|string $mod The modulus. Must be strictly positive. |
| 537 | 505 | * |
| 538 | - * @return BigInteger | |
| 539 | - * | |
| 540 | 506 | * @throws NegativeNumberException If any of the operands is negative. |
| 541 | 507 | * @throws DivisionByZeroException If the modulus is zero. |
| 542 | 508 | */ |
| 543 | - public function modPow($exp, $mod): BigInteger | |
| 509 | + public function modPow(BigNumber|int|float|string $exp, BigNumber|int|float|string $mod) : BigInteger | |
| 544 | 510 | { |
| 545 | 511 | $exp = BigInteger::of($exp); |
| 546 | 512 | $mod = BigInteger::of($mod); |
| 547 | 513 | if ($this->isNegative() || $exp->isNegative() || $mod->isNegative()) { |
| @@ -558,12 +524,10 @@ | ||
| 558 | 524 | * |
| 559 | 525 | * The GCD is always positive, unless both operands are zero, in which case it is zero. |
| 560 | 526 | * |
| 561 | 527 | * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. |
| 562 | - * | |
| 563 | - * @return BigInteger | |
| 564 | 528 | */ |
| 565 | - public function gcd($that): BigInteger | |
| 529 | + public function gcd(BigNumber|int|float|string $that) : BigInteger | |
| 566 | 530 | { |
| 567 | 531 | $that = BigInteger::of($that); |
| 568 | 532 | if ($that->value === '0' && $this->value[0] !== '-') { |
| 569 | 533 | return $this; |
| @@ -578,13 +542,11 @@ | ||
| 578 | 542 | * Returns the integer square root number of this number, rounded down. |
| 579 | 543 | * |
| 580 | 544 | * The result is the largest x such that x² ≤ n. |
| 581 | 545 | * |
| 582 | - * @return BigInteger | |
| 583 | - * | |
| 584 | 546 | * @throws NegativeNumberException If this number is negative. |
| 585 | 547 | */ |
| 586 | - public function sqrt(): BigInteger | |
| 548 | + public function sqrt() : BigInteger | |
| 587 | 549 | { |
| 588 | 550 | if ($this->value[0] === '-') { |
| 589 | 551 | throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); |
| 590 | 552 | } |
| @@ -592,21 +554,17 @@ | ||
| 592 | 554 | return new BigInteger($value); |
| 593 | 555 | } |
| 594 | 556 | /** |
| 595 | 557 | * Returns the absolute value of this number. |
| 596 | - * | |
| 597 | - * @return BigInteger | |
| 598 | 558 | */ |
| 599 | - public function abs(): BigInteger | |
| 559 | + public function abs() : BigInteger | |
| 600 | 560 | { |
| 601 | 561 | return $this->isNegative() ? $this->negated() : $this; |
| 602 | 562 | } |
| 603 | 563 | /** |
| 604 | 564 | * Returns the inverse of this number. |
| 605 | - * | |
| 606 | - * @return BigInteger | |
| 607 | 565 | */ |
| 608 | - public function negated(): BigInteger | |
| 566 | + public function negated() : BigInteger | |
| 609 | 567 | { |
| 610 | 568 | return new BigInteger(Calculator::get()->neg($this->value)); |
| 611 | 569 | } |
| 612 | 570 | /** |
| @@ -614,12 +572,10 @@ | ||
| 614 | 572 | * |
| 615 | 573 | * This method returns a negative BigInteger if and only if both operands are negative. |
| 616 | 574 | * |
| 617 | 575 | * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. |
| 618 | - * | |
| 619 | - * @return BigInteger | |
| 620 | 576 | */ |
| 621 | - public function and($that): BigInteger | |
| 577 | + public function and(BigNumber|int|float|string $that) : BigInteger | |
| 622 | 578 | { |
| 623 | 579 | $that = BigInteger::of($that); |
| 624 | 580 | return new BigInteger(Calculator::get()->and($this->value, $that->value)); |
| 625 | 581 | } |
| @@ -628,12 +584,10 @@ | ||
| 628 | 584 | * |
| 629 | 585 | * This method returns a negative BigInteger if and only if either of the operands is negative. |
| 630 | 586 | * |
| 631 | 587 | * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. |
| 632 | - * | |
| 633 | - * @return BigInteger | |
| 634 | 588 | */ |
| 635 | - public function or($that): BigInteger | |
| 589 | + public function or(BigNumber|int|float|string $that) : BigInteger | |
| 636 | 590 | { |
| 637 | 591 | $that = BigInteger::of($that); |
| 638 | 592 | return new BigInteger(Calculator::get()->or($this->value, $that->value)); |
| 639 | 593 | } |
| @@ -642,12 +596,10 @@ | ||
| 642 | 596 | * |
| 643 | 597 | * This method returns a negative BigInteger if and only if exactly one of the operands is negative. |
| 644 | 598 | * |
| 645 | 599 | * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. |
| 646 | - * | |
| 647 | - * @return BigInteger | |
| 648 | 600 | */ |
| 649 | - public function xor($that): BigInteger | |
| 601 | + public function xor(BigNumber|int|float|string $that) : BigInteger | |
| 650 | 602 | { |
| 651 | 603 | $that = BigInteger::of($that); |
| 652 | 604 | return new BigInteger(Calculator::get()->xor($this->value, $that->value)); |
| 653 | 605 | } |
| @@ -652,23 +604,17 @@ | ||
| 652 | 604 | return new BigInteger(Calculator::get()->xor($this->value, $that->value)); |
| 653 | 605 | } |
| 654 | 606 | /** |
| 655 | 607 | * Returns the bitwise-not of this BigInteger. |
| 656 | - * | |
| 657 | - * @return BigInteger | |
| 658 | 608 | */ |
| 659 | - public function not(): BigInteger | |
| 609 | + public function not() : BigInteger | |
| 660 | 610 | { |
| 661 | 611 | return $this->negated()->minus(1); |
| 662 | 612 | } |
| 663 | 613 | /** |
| 664 | 614 | * Returns the integer left shifted by a given number of bits. |
| 665 | - * | |
| 666 | - * @param int $distance The distance to shift. | |
| 667 | - * | |
| 668 | - * @return BigInteger | |
| 669 | 615 | */ |
| 670 | - public function shiftedLeft(int $distance): BigInteger | |
| 616 | + public function shiftedLeft(int $distance) : BigInteger | |
| 671 | 617 | { |
| 672 | 618 | if ($distance === 0) { |
| 673 | 619 | return $this; |
| 674 | 620 | } |
| @@ -678,14 +624,10 @@ | ||
| 678 | 624 | return $this->multipliedBy(BigInteger::of(2)->power($distance)); |
| 679 | 625 | } |
| 680 | 626 | /** |
| 681 | 627 | * Returns the integer right shifted by a given number of bits. |
| 682 | - * | |
| 683 | - * @param int $distance The distance to shift. | |
| 684 | - * | |
| 685 | - * @return BigInteger | |
| 686 | 628 | */ |
| 687 | - public function shiftedRight(int $distance): BigInteger | |
| 629 | + public function shiftedRight(int $distance) : BigInteger | |
| 688 | 630 | { |
| 689 | 631 | if ($distance === 0) { |
| 690 | 632 | return $this; |
| 691 | 633 | } |
| @@ -702,12 +644,10 @@ | ||
| 702 | 644 | * Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. |
| 703 | 645 | * |
| 704 | 646 | * For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. |
| 705 | 647 | * Computes (ceil(log2(this < 0 ? -this : this+1))). |
| 706 | - * | |
| 707 | - * @return int | |
| 708 | 648 | */ |
| 709 | - public function getBitLength(): int | |
| 649 | + public function getBitLength() : int | |
| 710 | 650 | { |
| 711 | 651 | if ($this->value === '0') { |
| 712 | 652 | return 0; |
| 713 | 653 | } |
| @@ -719,12 +659,10 @@ | ||
| 719 | 659 | /** |
| 720 | 660 | * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. |
| 721 | 661 | * |
| 722 | 662 | * Returns -1 if this BigInteger contains no one bits. |
| 723 | - * | |
| 724 | - * @return int | |
| 725 | 663 | */ |
| 726 | - public function getLowestSetBit(): int | |
| 664 | + public function getLowestSetBit() : int | |
| 727 | 665 | { |
| 728 | 666 | $n = $this; |
| 729 | 667 | $bitLength = $this->getBitLength(); |
| 730 | 668 | for ($i = 0; $i <= $bitLength; $i++) { |
| @@ -736,21 +674,17 @@ | ||
| 736 | 674 | return -1; |
| 737 | 675 | } |
| 738 | 676 | /** |
| 739 | 677 | * Returns whether this number is even. |
| 740 | - * | |
| 741 | - * @return bool | |
| 742 | 678 | */ |
| 743 | - public function isEven(): bool | |
| 679 | + public function isEven() : bool | |
| 744 | 680 | { |
| 745 | 681 | return \in_array($this->value[-1], ['0', '2', '4', '6', '8'], \true); |
| 746 | 682 | } |
| 747 | 683 | /** |
| 748 | 684 | * Returns whether this number is odd. |
| 749 | - * | |
| 750 | - * @return bool | |
| 751 | 685 | */ |
| 752 | - public function isOdd(): bool | |
| 686 | + public function isOdd() : bool | |
| 753 | 687 | { |
| 754 | 688 | return \in_array($this->value[-1], ['1', '3', '5', '7', '9'], \true); |
| 755 | 689 | } |
| 756 | 690 | /** |
| @@ -759,13 +693,11 @@ | ||
| 759 | 693 | * Computes ((this & (1<<n)) != 0). |
| 760 | 694 | * |
| 761 | 695 | * @param int $n The bit to test, 0-based. |
| 762 | 696 | * |
| 763 | - * @return bool | |
| 764 | - * | |
| 765 | 697 | * @throws \InvalidArgumentException If the bit to test is negative. |
| 766 | 698 | */ |
| 767 | - public function testBit(int $n): bool | |
| 699 | + public function testBit(int $n) : bool | |
| 768 | 700 | { |
| 769 | 701 | if ($n < 0) { |
| 770 | 702 | throw new \InvalidArgumentException('The bit to test cannot be negative.'); |
| 771 | 703 | } |
| @@ -770,12 +702,10 @@ | ||
| 770 | 702 | throw new \InvalidArgumentException('The bit to test cannot be negative.'); |
| 771 | 703 | } |
| 772 | 704 | return $this->shiftedRight($n)->isOdd(); |
| 773 | 705 | } |
| 774 | - /** | |
| 775 | - * {@inheritdoc} | |
| 776 | - */ | |
| 777 | - public function compareTo($that): int | |
| 706 | + #[\Override] | |
| 707 | + public function compareTo(BigNumber|int|float|string $that) : int | |
| 778 | 708 | { |
| 779 | 709 | $that = BigNumber::of($that); |
| 780 | 710 | if ($that instanceof BigInteger) { |
| 781 | 711 | return Calculator::get()->cmp($this->value, $that->value); |
| @@ -781,47 +711,35 @@ | ||
| 781 | 711 | return Calculator::get()->cmp($this->value, $that->value); |
| 782 | 712 | } |
| 783 | 713 | return -$that->compareTo($this); |
| 784 | 714 | } |
| 785 | - /** | |
| 786 | - * {@inheritdoc} | |
| 787 | - */ | |
| 788 | - public function getSign(): int | |
| 715 | + #[\Override] | |
| 716 | + public function getSign() : int | |
| 789 | 717 | { |
| 790 | 718 | return $this->value === '0' ? 0 : ($this->value[0] === '-' ? -1 : 1); |
| 791 | 719 | } |
| 792 | - /** | |
| 793 | - * {@inheritdoc} | |
| 794 | - */ | |
| 795 | - public function toBigInteger(): BigInteger | |
| 720 | + #[\Override] | |
| 721 | + public function toBigInteger() : BigInteger | |
| 796 | 722 | { |
| 797 | 723 | return $this; |
| 798 | 724 | } |
| 799 | - /** | |
| 800 | - * {@inheritdoc} | |
| 801 | - */ | |
| 802 | - public function toBigDecimal(): BigDecimal | |
| 725 | + #[\Override] | |
| 726 | + public function toBigDecimal() : BigDecimal | |
| 803 | 727 | { |
| 804 | - return BigDecimal::create($this->value); | |
| 728 | + return self::newBigDecimal($this->value); | |
| 805 | 729 | } |
| 806 | - /** | |
| 807 | - * {@inheritdoc} | |
| 808 | - */ | |
| 809 | - public function toBigRational(): BigRational | |
| 730 | + #[\Override] | |
| 731 | + public function toBigRational() : BigRational | |
| 810 | 732 | { |
| 811 | - return BigRational::create($this, BigInteger::one(), \false); | |
| 733 | + return self::newBigRational($this, BigInteger::one(), \false); | |
| 812 | 734 | } |
| 813 | - /** | |
| 814 | - * {@inheritdoc} | |
| 815 | - */ | |
| 816 | - public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY): BigDecimal | |
| 735 | + #[\Override] | |
| 736 | + public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal | |
| 817 | 737 | { |
| 818 | 738 | return $this->toBigDecimal()->toScale($scale, $roundingMode); |
| 819 | 739 | } |
| 820 | - /** | |
| 821 | - * {@inheritdoc} | |
| 822 | - */ | |
| 823 | - public function toInt(): int | |
| 740 | + #[\Override] | |
| 741 | + public function toInt() : int | |
| 824 | 742 | { |
| 825 | 743 | $intValue = (int) $this->value; |
| 826 | 744 | if ($this->value !== (string) $intValue) { |
| 827 | 745 | throw IntegerOverflowException::toIntOverflow($this); |
| @@ -827,12 +745,10 @@ | ||
| 827 | 745 | throw IntegerOverflowException::toIntOverflow($this); |
| 828 | 746 | } |
| 829 | 747 | return $intValue; |
| 830 | 748 | } |
| 831 | - /** | |
| 832 | - * {@inheritdoc} | |
| 833 | - */ | |
| 834 | - public function toFloat(): float | |
| 749 | + #[\Override] | |
| 750 | + public function toFloat() : float | |
| 835 | 751 | { |
| 836 | 752 | return (float) $this->value; |
| 837 | 753 | } |
| 838 | 754 | /** |
| @@ -839,15 +755,11 @@ | ||
| 839 | 755 | * Returns a string representation of this number in the given base. |
| 840 | 756 | * |
| 841 | 757 | * The output will always be lowercase for bases greater than 10. |
| 842 | 758 | * |
| 843 | - * @param int $base | |
| 844 | - * | |
| 845 | - * @return string | |
| 846 | - * | |
| 847 | 759 | * @throws \InvalidArgumentException If the base is out of range. |
| 848 | 760 | */ |
| 849 | - public function toBase(int $base): string | |
| 761 | + public function toBase(int $base) : string | |
| 850 | 762 | { |
| 851 | 763 | if ($base === 10) { |
| 852 | 764 | return $this->value; |
| 853 | 765 | } |
| @@ -863,14 +775,12 @@ | ||
| 863 | 775 | * a NegativeNumberException will be thrown when attempting to call this method on a negative number. |
| 864 | 776 | * |
| 865 | 777 | * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. |
| 866 | 778 | * |
| 867 | - * @return string | |
| 868 | - * | |
| 869 | 779 | * @throws NegativeNumberException If this number is negative. |
| 870 | 780 | * @throws \InvalidArgumentException If the given alphabet does not contain at least 2 chars. |
| 871 | 781 | */ |
| 872 | - public function toArbitraryBase(string $alphabet): string | |
| 782 | + public function toArbitraryBase(string $alphabet) : string | |
| 873 | 783 | { |
| 874 | 784 | $base = \strlen($alphabet); |
| 875 | 785 | if ($base < 2) { |
| 876 | 786 | throw new \InvalidArgumentException('The alphabet must contain at least 2 chars.'); |
| @@ -895,13 +805,11 @@ | ||
| 895 | 805 | * This representation is compatible with the `fromBytes()` factory method, as long as the `$signed` flags match. |
| 896 | 806 | * |
| 897 | 807 | * @param bool $signed Whether to output a signed number in two's-complement representation with a leading sign bit. |
| 898 | 808 | * |
| 899 | - * @return string | |
| 900 | - * | |
| 901 | 809 | * @throws NegativeNumberException If $signed is false, and the number is negative. |
| 902 | 810 | */ |
| 903 | - public function toBytes(bool $signed = \true): string | |
| 811 | + public function toBytes(bool $signed = \true) : string | |
| 904 | 812 | { |
| 905 | 813 | if (!$signed && $this->isNegative()) { |
| 906 | 814 | throw new NegativeNumberException('Cannot convert a negative number to a byte string when $signed is false.'); |
| 907 | 815 | } |
| @@ -912,9 +820,9 @@ | ||
| 912 | 820 | $baseHexLength = \strlen($hex); |
| 913 | 821 | if ($signed) { |
| 914 | 822 | if ($this->isNegative()) { |
| 915 | 823 | $bin = \hex2bin($hex); |
| 916 | - assert($bin !== \false); | |
| 824 | + \assert($bin !== \false); | |
| 917 | 825 | $hex = \bin2hex(~$bin); |
| 918 | 826 | $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); |
| 919 | 827 | $hexLength = \strlen($hex); |
| 920 | 828 | if ($hexLength < $baseHexLength) { |
| @@ -922,19 +830,23 @@ | ||
| 922 | 830 | } |
| 923 | 831 | if ($hex[0] < '8') { |
| 924 | 832 | $hex = 'FF' . $hex; |
| 925 | 833 | } |
| 926 | - } else if ($hex[0] >= '8') { | |
| 927 | - $hex = '00' . $hex; | |
| 834 | + } else { | |
| 835 | + if ($hex[0] >= '8') { | |
| 836 | + $hex = '00' . $hex; | |
| 837 | + } | |
| 928 | 838 | } |
| 929 | 839 | } |
| 930 | 840 | return \hex2bin($hex); |
| 931 | 841 | } |
| 932 | 842 | /** |
| 933 | - * {@inheritdoc} | |
| 843 | + * @return numeric-string | |
| 934 | 844 | */ |
| 935 | - public function __toString(): string | |
| 845 | + #[\Override] | |
| 846 | + public function __toString() : string | |
| 936 | 847 | { |
| 848 | + /** @var numeric-string */ | |
| 937 | 849 | return $this->value; |
| 938 | 850 | } |
| 939 | 851 | /** |
| 940 | 852 | * This method is required for serializing the object and SHOULD NOT be accessed directly. |
| @@ -942,9 +854,9 @@ | ||
| 942 | 854 | * @internal |
| 943 | 855 | * |
| 944 | 856 | * @return array{value: string} |
| 945 | 857 | */ |
| 946 | - public function __serialize(): array | |
| 858 | + public function __serialize() : array | |
| 947 | 859 | { |
| 948 | 860 | return ['value' => $this->value]; |
| 949 | 861 | } |
| 950 | 862 | /** |
| @@ -954,46 +866,14 @@ | ||
| 954 | 866 | * @psalm-suppress RedundantPropertyInitializationCheck |
| 955 | 867 | * |
| 956 | 868 | * @param array{value: string} $data |
| 957 | 869 | * |
| 958 | - * @return void | |
| 959 | - * | |
| 960 | 870 | * @throws \LogicException |
| 961 | 871 | */ |
| 962 | - public function __unserialize(array $data): void | |
| 872 | + public function __unserialize(array $data) : void | |
| 963 | 873 | { |
| 964 | 874 | if (isset($this->value)) { |
| 965 | 875 | throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); |
| 966 | 876 | } |
| 967 | 877 | $this->value = $data['value']; |
| 968 | - } | |
| 969 | - /** | |
| 970 | - * This method is required by interface Serializable and SHOULD NOT be accessed directly. | |
| 971 | - * | |
| 972 | - * @internal | |
| 973 | - * | |
| 974 | - * @return string | |
| 975 | - */ | |
| 976 | - public function serialize(): string | |
| 977 | - { | |
| 978 | - return $this->value; | |
| 979 | - } | |
| 980 | - /** | |
| 981 | - * This method is only here to implement interface Serializable and cannot be accessed directly. | |
| 982 | - * | |
| 983 | - * @internal | |
| 984 | - * @psalm-suppress RedundantPropertyInitializationCheck | |
| 985 | - * | |
| 986 | - * @param string $value | |
| 987 | - * | |
| 988 | - * @return void | |
| 989 | - * | |
| 990 | - * @throws \LogicException | |
| 991 | - */ | |
| 992 | - public function unserialize($value): void | |
| 993 | - { | |
| 994 | - if (isset($this->value)) { | |
| 995 | - throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); | |
| 996 | - } | |
| 997 | - $this->value = $value; | |
| 998 | 878 | } |
| 999 | 879 | } |