[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/brick/math/src/ -> BigRational.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer