[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace Brick\Math; 6 7 use Brick\Math\Exception\DivisionByZeroException; 8 use Brick\Math\Exception\MathException; 9 use Brick\Math\Exception\NumberFormatException; 10 use Brick\Math\Exception\RoundingNecessaryException; 11 12 /** 13 * An arbitrarily large rational number. 14 * 15 * This class is immutable. 16 * 17 * @psalm-immutable 18 */ 19 final class BigRational extends BigNumber 20 { 21 /** 22 * The numerator. 23 * 24 * @var BigInteger 25 */ 26 private $numerator; 27 28 /** 29 * The denominator. Always strictly positive. 30 * 31 * @var BigInteger 32 */ 33 private $denominator; 34 35 /** 36 * Protected constructor. Use a factory method to obtain an instance. 37 * 38 * @param BigInteger $numerator The numerator. 39 * @param BigInteger $denominator The denominator. 40 * @param bool $checkDenominator Whether to check the denominator for negative and zero. 41 * 42 * @throws DivisionByZeroException If the denominator is zero. 43 */ 44 protected function __construct(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) 45 { 46 if ($checkDenominator) { 47 if ($denominator->isZero()) { 48 throw DivisionByZeroException::denominatorMustNotBeZero(); 49 } 50 51 if ($denominator->isNegative()) { 52 $numerator = $numerator->negated(); 53 $denominator = $denominator->negated(); 54 } 55 } 56 57 $this->numerator = $numerator; 58 $this->denominator = $denominator; 59 } 60 61 /** 62 * Creates a BigRational of the given value. 63 * 64 * @param BigNumber|int|float|string $value 65 * 66 * @return BigRational 67 * 68 * @throws MathException If the value cannot be converted to a BigRational. 69 * 70 * @psalm-pure 71 */ 72 public static function of($value) : BigNumber 73 { 74 return parent::of($value)->toBigRational(); 75 } 76 77 /** 78 * Creates a BigRational out of a numerator and a denominator. 79 * 80 * If the denominator is negative, the signs of both the numerator and the denominator 81 * will be inverted to ensure that the denominator is always positive. 82 * 83 * @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger. 84 * @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger. 85 * 86 * @return BigRational 87 * 88 * @throws NumberFormatException If an argument does not represent a valid number. 89 * @throws RoundingNecessaryException If an argument represents a non-integer number. 90 * @throws DivisionByZeroException If the denominator is zero. 91 * 92 * @psalm-pure 93 */ 94 public static function nd($numerator, $denominator) : BigRational 95 { 96 $numerator = BigInteger::of($numerator); 97 $denominator = BigInteger::of($denominator); 98 99 return new BigRational($numerator, $denominator, true); 100 } 101 102 /** 103 * Returns a BigRational representing zero. 104 * 105 * @return BigRational 106 * 107 * @psalm-pure 108 */ 109 public static function zero() : BigRational 110 { 111 /** @psalm-suppress ImpureStaticVariable */ 112 static $zero; 113 114 if ($zero === null) { 115 $zero = new BigRational(BigInteger::zero(), BigInteger::one(), false); 116 } 117 118 return $zero; 119 } 120 121 /** 122 * Returns a BigRational representing one. 123 * 124 * @return BigRational 125 * 126 * @psalm-pure 127 */ 128 public static function one() : BigRational 129 { 130 /** @psalm-suppress ImpureStaticVariable */ 131 static $one; 132 133 if ($one === null) { 134 $one = new BigRational(BigInteger::one(), BigInteger::one(), false); 135 } 136 137 return $one; 138 } 139 140 /** 141 * Returns a BigRational representing ten. 142 * 143 * @return BigRational 144 * 145 * @psalm-pure 146 */ 147 public static function ten() : BigRational 148 { 149 /** @psalm-suppress ImpureStaticVariable */ 150 static $ten; 151 152 if ($ten === null) { 153 $ten = new BigRational(BigInteger::ten(), BigInteger::one(), false); 154 } 155 156 return $ten; 157 } 158 159 /** 160 * @return BigInteger 161 */ 162 public function getNumerator() : BigInteger 163 { 164 return $this->numerator; 165 } 166 167 /** 168 * @return BigInteger 169 */ 170 public function getDenominator() : BigInteger 171 { 172 return $this->denominator; 173 } 174 175 /** 176 * Returns the quotient of the division of the numerator by the denominator. 177 * 178 * @return BigInteger 179 */ 180 public function quotient() : BigInteger 181 { 182 return $this->numerator->quotient($this->denominator); 183 } 184 185 /** 186 * Returns the remainder of the division of the numerator by the denominator. 187 * 188 * @return BigInteger 189 */ 190 public function remainder() : BigInteger 191 { 192 return $this->numerator->remainder($this->denominator); 193 } 194 195 /** 196 * Returns the quotient and remainder of the division of the numerator by the denominator. 197 * 198 * @return BigInteger[] 199 */ 200 public function quotientAndRemainder() : array 201 { 202 return $this->numerator->quotientAndRemainder($this->denominator); 203 } 204 205 /** 206 * Returns the sum of this number and the given one. 207 * 208 * @param BigNumber|int|float|string $that The number to add. 209 * 210 * @return BigRational The result. 211 * 212 * @throws MathException If the number is not valid. 213 */ 214 public function plus($that) : BigRational 215 { 216 $that = BigRational::of($that); 217 218 $numerator = $this->numerator->multipliedBy($that->denominator); 219 $numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator)); 220 $denominator = $this->denominator->multipliedBy($that->denominator); 221 222 return new BigRational($numerator, $denominator, false); 223 } 224 225 /** 226 * Returns the difference of this number and the given one. 227 * 228 * @param BigNumber|int|float|string $that The number to subtract. 229 * 230 * @return BigRational The result. 231 * 232 * @throws MathException If the number is not valid. 233 */ 234 public function minus($that) : BigRational 235 { 236 $that = BigRational::of($that); 237 238 $numerator = $this->numerator->multipliedBy($that->denominator); 239 $numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator)); 240 $denominator = $this->denominator->multipliedBy($that->denominator); 241 242 return new BigRational($numerator, $denominator, false); 243 } 244 245 /** 246 * Returns the product of this number and the given one. 247 * 248 * @param BigNumber|int|float|string $that The multiplier. 249 * 250 * @return BigRational The result. 251 * 252 * @throws MathException If the multiplier is not a valid number. 253 */ 254 public function multipliedBy($that) : BigRational 255 { 256 $that = BigRational::of($that); 257 258 $numerator = $this->numerator->multipliedBy($that->numerator); 259 $denominator = $this->denominator->multipliedBy($that->denominator); 260 261 return new BigRational($numerator, $denominator, false); 262 } 263 264 /** 265 * Returns the result of the division of this number by the given one. 266 * 267 * @param BigNumber|int|float|string $that The divisor. 268 * 269 * @return BigRational The result. 270 * 271 * @throws MathException If the divisor is not a valid number, or is zero. 272 */ 273 public function dividedBy($that) : BigRational 274 { 275 $that = BigRational::of($that); 276 277 $numerator = $this->numerator->multipliedBy($that->denominator); 278 $denominator = $this->denominator->multipliedBy($that->numerator); 279 280 return new BigRational($numerator, $denominator, true); 281 } 282 283 /** 284 * Returns this number exponentiated to the given value. 285 * 286 * @param int $exponent The exponent. 287 * 288 * @return BigRational The result. 289 * 290 * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. 291 */ 292 public function power(int $exponent) : BigRational 293 { 294 if ($exponent === 0) { 295 $one = BigInteger::one(); 296 297 return new BigRational($one, $one, false); 298 } 299 300 if ($exponent === 1) { 301 return $this; 302 } 303 304 return new BigRational( 305 $this->numerator->power($exponent), 306 $this->denominator->power($exponent), 307 false 308 ); 309 } 310 311 /** 312 * Returns the reciprocal of this BigRational. 313 * 314 * The reciprocal has the numerator and denominator swapped. 315 * 316 * @return BigRational 317 * 318 * @throws DivisionByZeroException If the numerator is zero. 319 */ 320 public function reciprocal() : BigRational 321 { 322 return new BigRational($this->denominator, $this->numerator, true); 323 } 324 325 /** 326 * Returns the absolute value of this BigRational. 327 * 328 * @return BigRational 329 */ 330 public function abs() : BigRational 331 { 332 return new BigRational($this->numerator->abs(), $this->denominator, false); 333 } 334 335 /** 336 * Returns the negated value of this BigRational. 337 * 338 * @return BigRational 339 */ 340 public function negated() : BigRational 341 { 342 return new BigRational($this->numerator->negated(), $this->denominator, false); 343 } 344 345 /** 346 * Returns the simplified value of this BigRational. 347 * 348 * @return BigRational 349 */ 350 public function simplified() : BigRational 351 { 352 $gcd = $this->numerator->gcd($this->denominator); 353 354 $numerator = $this->numerator->quotient($gcd); 355 $denominator = $this->denominator->quotient($gcd); 356 357 return new BigRational($numerator, $denominator, false); 358 } 359 360 /** 361 * {@inheritdoc} 362 */ 363 public function compareTo($that) : int 364 { 365 return $this->minus($that)->getSign(); 366 } 367 368 /** 369 * {@inheritdoc} 370 */ 371 public function getSign() : int 372 { 373 return $this->numerator->getSign(); 374 } 375 376 /** 377 * {@inheritdoc} 378 */ 379 public function toBigInteger() : BigInteger 380 { 381 $simplified = $this->simplified(); 382 383 if (! $simplified->denominator->isEqualTo(1)) { 384 throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.'); 385 } 386 387 return $simplified->numerator; 388 } 389 390 /** 391 * {@inheritdoc} 392 */ 393 public function toBigDecimal() : BigDecimal 394 { 395 return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator); 396 } 397 398 /** 399 * {@inheritdoc} 400 */ 401 public function toBigRational() : BigRational 402 { 403 return $this; 404 } 405 406 /** 407 * {@inheritdoc} 408 */ 409 public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal 410 { 411 return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode); 412 } 413 414 /** 415 * {@inheritdoc} 416 */ 417 public function toInt() : int 418 { 419 return $this->toBigInteger()->toInt(); 420 } 421 422 /** 423 * {@inheritdoc} 424 */ 425 public function toFloat() : float 426 { 427 return $this->numerator->toFloat() / $this->denominator->toFloat(); 428 } 429 430 /** 431 * {@inheritdoc} 432 */ 433 public function __toString() : string 434 { 435 $numerator = (string) $this->numerator; 436 $denominator = (string) $this->denominator; 437 438 if ($denominator === '1') { 439 return $numerator; 440 } 441 442 return $this->numerator . '/' . $this->denominator; 443 } 444 445 /** 446 * This method is required by interface Serializable and SHOULD NOT be accessed directly. 447 * 448 * @internal 449 * 450 * @return string 451 */ 452 public function serialize() : string 453 { 454 return $this->numerator . '/' . $this->denominator; 455 } 456 457 /** 458 * This method is only here to implement interface Serializable and cannot be accessed directly. 459 * 460 * @internal 461 * 462 * @param string $value 463 * 464 * @return void 465 * 466 * @throws \LogicException 467 */ 468 public function unserialize($value) : void 469 { 470 if (isset($this->numerator)) { 471 throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); 472 } 473 474 [$numerator, $denominator] = \explode('/', $value); 475 476 $this->numerator = BigInteger::of($numerator); 477 $this->denominator = BigInteger::of($denominator); 478 } 479 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |