| @@ -57,32 +57,8 @@ | ||
| 57 | 57 | return parent::of($value)->toBigInteger(); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | /** |
| 61 | - * Parses a string containing an integer in an arbitrary base. | |
| 62 | - * | |
| 63 | - * @deprecated will be removed in version 0.9 - use fromBase() instead | |
| 64 | - * | |
| 65 | - * The string can optionally be prefixed with the `+` or `-` sign. | |
| 66 | - * For bases greater than 10, both uppercase and lowercase letters are allowed. | |
| 67 | - * | |
| 68 | - * @param string $number The number to parse. | |
| 69 | - * @param int $base The base of the number, between 2 and 36. | |
| 70 | - * | |
| 71 | - * @return BigInteger | |
| 72 | - * | |
| 73 | - * @throws \InvalidArgumentException If the number is invalid or the base is out of range. | |
| 74 | - */ | |
| 75 | - public static function parse(string $number, int $base = 10) : BigInteger | |
| 76 | - { | |
| 77 | - try { | |
| 78 | - return self::fromBase($number, $base); | |
| 79 | - } catch (NumberFormatException $e) { | |
| 80 | - throw new \InvalidArgumentException($e->getMessage(), 0, $e); | |
| 81 | - } | |
| 82 | - } | |
| 83 | - | |
| 84 | - /** | |
| 85 | 61 | * Creates a number from a string in a given base. |
| 86 | 62 | * |
| 87 | 63 | * The string can optionally be prefixed with the `+` or `-` sign. |
| 88 | 64 | * |
| @@ -219,9 +195,9 @@ | ||
| 219 | 195 | |
| 220 | 196 | $twosComplement = false; |
| 221 | 197 | |
| 222 | 198 | if ($signed) { |
| 223 | - $x = ord($value[0]); | |
| 199 | + $x = \ord($value[0]); | |
| 224 | 200 | |
| 225 | 201 | if (($twosComplement = ($x >= 0x80))) { |
| 226 | 202 | $value = ~$value; |
| 227 | 203 | } |
| @@ -226,9 +202,9 @@ | ||
| 226 | 202 | $value = ~$value; |
| 227 | 203 | } |
| 228 | 204 | } |
| 229 | 205 | |
| 230 | - $number = self::fromBase(bin2hex($value), 16); | |
| 206 | + $number = self::fromBase(\bin2hex($value), 16); | |
| 231 | 207 | |
| 232 | 208 | if ($twosComplement) { |
| 233 | 209 | return $number->plus(1)->negated(); |
| 234 | 210 | } |
| @@ -240,8 +216,10 @@ | ||
| 240 | 216 | * Generates a pseudo-random number in the range 0 to 2^numBits - 1. |
| 241 | 217 | * |
| 242 | 218 | * Using the default random bytes generator, this method is suitable for cryptographic use. |
| 243 | 219 | * |
| 220 | + * @psalm-param callable(int): string $randomBytesGenerator | |
| 221 | + * | |
| 244 | 222 | * @param int $numBits The number of bits. |
| 245 | 223 | * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a |
| 246 | 224 | * string of random bytes of the given length. Defaults to the |
| 247 | 225 | * `random_bytes()` function. |
| @@ -263,12 +241,12 @@ | ||
| 263 | 241 | if ($randomBytesGenerator === null) { |
| 264 | 242 | $randomBytesGenerator = 'random_bytes'; |
| 265 | 243 | } |
| 266 | 244 | |
| 267 | - $byteLength = intdiv($numBits - 1, 8) + 1; | |
| 245 | + $byteLength = \intdiv($numBits - 1, 8) + 1; | |
| 268 | 246 | |
| 269 | 247 | $extraBits = ($byteLength * 8 - $numBits); |
| 270 | - $bitmask = chr(0xFF >> $extraBits); | |
| 248 | + $bitmask = \chr(0xFF >> $extraBits); | |
| 271 | 249 | |
| 272 | 250 | $randomBytes = $randomBytesGenerator($byteLength); |
| 273 | 251 | $randomBytes[0] = $randomBytes[0] & $bitmask; |
| 274 | 252 | |
| @@ -279,8 +257,10 @@ | ||
| 279 | 257 | * Generates a pseudo-random number between `$min` and `$max`. |
| 280 | 258 | * |
| 281 | 259 | * Using the default random bytes generator, this method is suitable for cryptographic use. |
| 282 | 260 | * |
| 261 | + * @psalm-param (callable(int): string)|null $randomBytesGenerator | |
| 262 | + * | |
| 283 | 263 | * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. |
| 284 | 264 | * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. |
| 285 | 265 | * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, |
| 286 | 266 | * and returns a string of random bytes of the given length. |
| @@ -323,9 +303,12 @@ | ||
| 323 | 303 | * @psalm-pure |
| 324 | 304 | */ |
| 325 | 305 | public static function zero() : BigInteger |
| 326 | 306 | { |
| 327 | - /** @psalm-suppress ImpureStaticVariable */ | |
| 307 | + /** | |
| 308 | + * @psalm-suppress ImpureStaticVariable | |
| 309 | + * @var BigInteger|null $zero | |
| 310 | + */ | |
| 328 | 311 | static $zero; |
| 329 | 312 | |
| 330 | 313 | if ($zero === null) { |
| 331 | 314 | $zero = new BigInteger('0'); |
| @@ -342,9 +325,12 @@ | ||
| 342 | 325 | * @psalm-pure |
| 343 | 326 | */ |
| 344 | 327 | public static function one() : BigInteger |
| 345 | 328 | { |
| 346 | - /** @psalm-suppress ImpureStaticVariable */ | |
| 329 | + /** | |
| 330 | + * @psalm-suppress ImpureStaticVariable | |
| 331 | + * @var BigInteger|null $one | |
| 332 | + */ | |
| 347 | 333 | static $one; |
| 348 | 334 | |
| 349 | 335 | if ($one === null) { |
| 350 | 336 | $one = new BigInteger('1'); |
| @@ -361,9 +347,12 @@ | ||
| 361 | 347 | * @psalm-pure |
| 362 | 348 | */ |
| 363 | 349 | public static function ten() : BigInteger |
| 364 | 350 | { |
| 365 | - /** @psalm-suppress ImpureStaticVariable */ | |
| 351 | + /** | |
| 352 | + * @psalm-suppress ImpureStaticVariable | |
| 353 | + * @var BigInteger|null $ten | |
| 354 | + */ | |
| 366 | 355 | static $ten; |
| 367 | 356 | |
| 368 | 357 | if ($ten === null) { |
| 369 | 358 | $ten = new BigInteger('10'); |
| @@ -649,10 +638,10 @@ | ||
| 649 | 638 | * Returns this number raised into power with modulo. |
| 650 | 639 | * |
| 651 | 640 | * This operation only works on positive numbers. |
| 652 | 641 | * |
| 653 | - * @param BigNumber|int|float|string $exp The positive exponent. | |
| 654 | - * @param BigNumber|int|float|string $mod The modulus. Must not be zero. | |
| 642 | + * @param BigNumber|int|float|string $exp The exponent. Must be positive or zero. | |
| 643 | + * @param BigNumber|int|float|string $mod The modulus. Must be strictly positive. | |
| 655 | 644 | * |
| 656 | 645 | * @return BigInteger |
| 657 | 646 | * |
| 658 | 647 | * @throws NegativeNumberException If any of the operands is negative. |
| @@ -676,26 +665,8 @@ | ||
| 676 | 665 | return new BigInteger($result); |
| 677 | 666 | } |
| 678 | 667 | |
| 679 | 668 | /** |
| 680 | - * Returns this number raised into power with modulo. | |
| 681 | - * | |
| 682 | - * @deprecated Use modPow() instead. | |
| 683 | - * | |
| 684 | - * @param BigNumber|int|float|string $exp The positive exponent. | |
| 685 | - * @param BigNumber|int|float|string $mod The modulus. Must not be zero. | |
| 686 | - * | |
| 687 | - * @return BigInteger | |
| 688 | - * | |
| 689 | - * @throws NegativeNumberException If any of the operands is negative. | |
| 690 | - * @throws DivisionByZeroException If the modulus is zero. | |
| 691 | - */ | |
| 692 | - public function powerMod($exp, $mod) : BigInteger | |
| 693 | - { | |
| 694 | - return $this->modPow($exp, $mod); | |
| 695 | - } | |
| 696 | - | |
| 697 | - /** | |
| 698 | 669 | * Returns the greatest common divisor of this number and the given one. |
| 699 | 670 | * |
| 700 | 671 | * The GCD is always positive, unless both operands are zero, in which case it is zero. |
| 701 | 672 | * |
| @@ -808,8 +779,18 @@ | ||
| 808 | 779 | return new BigInteger(Calculator::get()->xor($this->value, $that->value)); |
| 809 | 780 | } |
| 810 | 781 | |
| 811 | 782 | /** |
| 783 | + * Returns the bitwise-not of this BigInteger. | |
| 784 | + * | |
| 785 | + * @return BigInteger | |
| 786 | + */ | |
| 787 | + public function not() : BigInteger | |
| 788 | + { | |
| 789 | + return $this->negated()->minus(1); | |
| 790 | + } | |
| 791 | + | |
| 792 | + /** | |
| 812 | 793 | * Returns the integer left shifted by a given number of bits. |
| 813 | 794 | * |
| 814 | 795 | * @param int $distance The distance to shift. |
| 815 | 796 | * |
| @@ -871,9 +852,9 @@ | ||
| 871 | 852 | if ($this->isNegative()) { |
| 872 | 853 | return $this->abs()->minus(1)->getBitLength(); |
| 873 | 854 | } |
| 874 | 855 | |
| 875 | - return strlen($this->toBase(2)); | |
| 856 | + return \strlen($this->toBase(2)); | |
| 876 | 857 | } |
| 877 | 858 | |
| 878 | 859 | /** |
| 879 | 860 | * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. |
| @@ -904,9 +885,9 @@ | ||
| 904 | 885 | * @return bool |
| 905 | 886 | */ |
| 906 | 887 | public function isEven() : bool |
| 907 | 888 | { |
| 908 | - return in_array($this->value[-1], ['0', '2', '4', '6', '8'], true); | |
| 889 | + return \in_array($this->value[-1], ['0', '2', '4', '6', '8'], true); | |
| 909 | 890 | } |
| 910 | 891 | |
| 911 | 892 | /** |
| 912 | 893 | * Returns whether this number is odd. |
| @@ -914,9 +895,9 @@ | ||
| 914 | 895 | * @return bool |
| 915 | 896 | */ |
| 916 | 897 | public function isOdd() : bool |
| 917 | 898 | { |
| 918 | - return in_array($this->value[-1], ['1', '3', '5', '7', '9'], true); | |
| 899 | + return \in_array($this->value[-1], ['1', '3', '5', '7', '9'], true); | |
| 919 | 900 | } |
| 920 | 901 | |
| 921 | 902 | /** |
| 922 | 903 | * Returns true if and only if the designated bit is set. |
| @@ -1093,23 +1074,26 @@ | ||
| 1093 | 1074 | } |
| 1094 | 1075 | |
| 1095 | 1076 | $hex = $this->abs()->toBase(16); |
| 1096 | 1077 | |
| 1097 | - if (strlen($hex) % 2 !== 0) { | |
| 1078 | + if (\strlen($hex) % 2 !== 0) { | |
| 1098 | 1079 | $hex = '0' . $hex; |
| 1099 | 1080 | } |
| 1100 | 1081 | |
| 1101 | - $baseHexLength = strlen($hex); | |
| 1082 | + $baseHexLength = \strlen($hex); | |
| 1102 | 1083 | |
| 1103 | 1084 | if ($signed) { |
| 1104 | 1085 | if ($this->isNegative()) { |
| 1105 | - $hex = bin2hex(~hex2bin($hex)); | |
| 1086 | + $bin = \hex2bin($hex); | |
| 1087 | + assert($bin !== false); | |
| 1088 | + | |
| 1089 | + $hex = \bin2hex(~$bin); | |
| 1106 | 1090 | $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); |
| 1107 | 1091 | |
| 1108 | - $hexLength = strlen($hex); | |
| 1092 | + $hexLength = \strlen($hex); | |
| 1109 | 1093 | |
| 1110 | 1094 | if ($hexLength < $baseHexLength) { |
| 1111 | - $hex = str_repeat('0', $baseHexLength - $hexLength) . $hex; | |
| 1095 | + $hex = \str_repeat('0', $baseHexLength - $hexLength) . $hex; | |
| 1112 | 1096 | } |
| 1113 | 1097 | |
| 1114 | 1098 | if ($hex[0] < '8') { |
| 1115 | 1099 | $hex = 'FF' . $hex; |
| @@ -1120,9 +1104,9 @@ | ||
| 1120 | 1104 | } |
| 1121 | 1105 | } |
| 1122 | 1106 | } |
| 1123 | 1107 | |
| 1124 | - return hex2bin($hex); | |
| 1108 | + return \hex2bin($hex); | |
| 1125 | 1109 | } |
| 1126 | 1110 | |
| 1127 | 1111 | /** |
| 1128 | 1112 | * {@inheritdoc} |
| @@ -1132,8 +1116,41 @@ | ||
| 1132 | 1116 | return $this->value; |
| 1133 | 1117 | } |
| 1134 | 1118 | |
| 1135 | 1119 | /** |
| 1120 | + * This method is required for serializing the object and SHOULD NOT be accessed directly. | |
| 1121 | + * | |
| 1122 | + * @internal | |
| 1123 | + * | |
| 1124 | + * @return array{value: string} | |
| 1125 | + */ | |
| 1126 | + public function __serialize(): array | |
| 1127 | + { | |
| 1128 | + return ['value' => $this->value]; | |
| 1129 | + } | |
| 1130 | + | |
| 1131 | + /** | |
| 1132 | + * This method is only here to allow unserializing the object and cannot be accessed directly. | |
| 1133 | + * | |
| 1134 | + * @internal | |
| 1135 | + * @psalm-suppress RedundantPropertyInitializationCheck | |
| 1136 | + * | |
| 1137 | + * @param array{value: string} $data | |
| 1138 | + * | |
| 1139 | + * @return void | |
| 1140 | + * | |
| 1141 | + * @throws \LogicException | |
| 1142 | + */ | |
| 1143 | + public function __unserialize(array $data): void | |
| 1144 | + { | |
| 1145 | + if (isset($this->value)) { | |
| 1146 | + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); | |
| 1147 | + } | |
| 1148 | + | |
| 1149 | + $this->value = $data['value']; | |
| 1150 | + } | |
| 1151 | + | |
| 1152 | + /** | |
| 1136 | 1153 | * This method is required by interface Serializable and SHOULD NOT be accessed directly. |
| 1137 | 1154 | * |
| 1138 | 1155 | * @internal |
| 1139 | 1156 | * |
| @@ -1147,8 +1164,9 @@ | ||
| 1147 | 1164 | /** |
| 1148 | 1165 | * This method is only here to implement interface Serializable and cannot be accessed directly. |
| 1149 | 1166 | * |
| 1150 | 1167 | * @internal |
| 1168 | + * @psalm-suppress RedundantPropertyInitializationCheck | |
| 1151 | 1169 | * |
| 1152 | 1170 | * @param string $value |
| 1153 | 1171 | * |
| 1154 | 1172 | * @return void |