Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/vendor/brick/math/src/BigRational.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
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 + /**
112 + * @psalm-suppress ImpureStaticVariable
113 + * @var BigRational|null $zero
114 + */
115 + static $zero;
116 +
117 + if ($zero === null) {
118 + $zero = new BigRational(BigInteger::zero(), BigInteger::one(), false);
119 + }
120 +
121 + return $zero;
122 + }
123 +
124 + /**
125 + * Returns a BigRational representing one.
126 + *
127 + * @return BigRational
128 + *
129 + * @psalm-pure
130 + */
131 + public static function one() : BigRational
132 + {
133 + /**
134 + * @psalm-suppress ImpureStaticVariable
135 + * @var BigRational|null $one
136 + */
137 + static $one;
138 +
139 + if ($one === null) {
140 + $one = new BigRational(BigInteger::one(), BigInteger::one(), false);
141 + }
142 +
143 + return $one;
144 + }
145 +
146 + /**
147 + * Returns a BigRational representing ten.
148 + *
149 + * @return BigRational
150 + *
151 + * @psalm-pure
152 + */
153 + public static function ten() : BigRational
154 + {
155 + /**
156 + * @psalm-suppress ImpureStaticVariable
157 + * @var BigRational|null $ten
158 + */
159 + static $ten;
160 +
161 + if ($ten === null) {
162 + $ten = new BigRational(BigInteger::ten(), BigInteger::one(), false);
163 + }
164 +
165 + return $ten;
166 + }
167 +
168 + /**
169 + * @return BigInteger
170 + */
171 + public function getNumerator() : BigInteger
172 + {
173 + return $this->numerator;
174 + }
175 +
176 + /**
177 + * @return BigInteger
178 + */
179 + public function getDenominator() : BigInteger
180 + {
181 + return $this->denominator;
182 + }
183 +
184 + /**
185 + * Returns the quotient of the division of the numerator by the denominator.
186 + *
187 + * @return BigInteger
188 + */
189 + public function quotient() : BigInteger
190 + {
191 + return $this->numerator->quotient($this->denominator);
192 + }
193 +
194 + /**
195 + * Returns the remainder of the division of the numerator by the denominator.
196 + *
197 + * @return BigInteger
198 + */
199 + public function remainder() : BigInteger
200 + {
201 + return $this->numerator->remainder($this->denominator);
202 + }
203 +
204 + /**
205 + * Returns the quotient and remainder of the division of the numerator by the denominator.
206 + *
207 + * @return BigInteger[]
208 + */
209 + public function quotientAndRemainder() : array
210 + {
211 + return $this->numerator->quotientAndRemainder($this->denominator);
212 + }
213 +
214 + /**
215 + * Returns the sum of this number and the given one.
216 + *
217 + * @param BigNumber|int|float|string $that The number to add.
218 + *
219 + * @return BigRational The result.
220 + *
221 + * @throws MathException If the number is not valid.
222 + */
223 + public function plus($that) : BigRational
224 + {
225 + $that = BigRational::of($that);
226 +
227 + $numerator = $this->numerator->multipliedBy($that->denominator);
228 + $numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
229 + $denominator = $this->denominator->multipliedBy($that->denominator);
230 +
231 + return new BigRational($numerator, $denominator, false);
232 + }
233 +
234 + /**
235 + * Returns the difference of this number and the given one.
236 + *
237 + * @param BigNumber|int|float|string $that The number to subtract.
238 + *
239 + * @return BigRational The result.
240 + *
241 + * @throws MathException If the number is not valid.
242 + */
243 + public function minus($that) : BigRational
244 + {
245 + $that = BigRational::of($that);
246 +
247 + $numerator = $this->numerator->multipliedBy($that->denominator);
248 + $numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
249 + $denominator = $this->denominator->multipliedBy($that->denominator);
250 +
251 + return new BigRational($numerator, $denominator, false);
252 + }
253 +
254 + /**
255 + * Returns the product of this number and the given one.
256 + *
257 + * @param BigNumber|int|float|string $that The multiplier.
258 + *
259 + * @return BigRational The result.
260 + *
261 + * @throws MathException If the multiplier is not a valid number.
262 + */
263 + public function multipliedBy($that) : BigRational
264 + {
265 + $that = BigRational::of($that);
266 +
267 + $numerator = $this->numerator->multipliedBy($that->numerator);
268 + $denominator = $this->denominator->multipliedBy($that->denominator);
269 +
270 + return new BigRational($numerator, $denominator, false);
271 + }
272 +
273 + /**
274 + * Returns the result of the division of this number by the given one.
275 + *
276 + * @param BigNumber|int|float|string $that The divisor.
277 + *
278 + * @return BigRational The result.
279 + *
280 + * @throws MathException If the divisor is not a valid number, or is zero.
281 + */
282 + public function dividedBy($that) : BigRational
283 + {
284 + $that = BigRational::of($that);
285 +
286 + $numerator = $this->numerator->multipliedBy($that->denominator);
287 + $denominator = $this->denominator->multipliedBy($that->numerator);
288 +
289 + return new BigRational($numerator, $denominator, true);
290 + }
291 +
292 + /**
293 + * Returns this number exponentiated to the given value.
294 + *
295 + * @param int $exponent The exponent.
296 + *
297 + * @return BigRational The result.
298 + *
299 + * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000.
300 + */
301 + public function power(int $exponent) : BigRational
302 + {
303 + if ($exponent === 0) {
304 + $one = BigInteger::one();
305 +
306 + return new BigRational($one, $one, false);
307 + }
308 +
309 + if ($exponent === 1) {
310 + return $this;
311 + }
312 +
313 + return new BigRational(
314 + $this->numerator->power($exponent),
315 + $this->denominator->power($exponent),
316 + false
317 + );
318 + }
319 +
320 + /**
321 + * Returns the reciprocal of this BigRational.
322 + *
323 + * The reciprocal has the numerator and denominator swapped.
324 + *
325 + * @return BigRational
326 + *
327 + * @throws DivisionByZeroException If the numerator is zero.
328 + */
329 + public function reciprocal() : BigRational
330 + {
331 + return new BigRational($this->denominator, $this->numerator, true);
332 + }
333 +
334 + /**
335 + * Returns the absolute value of this BigRational.
336 + *
337 + * @return BigRational
338 + */
339 + public function abs() : BigRational
340 + {
341 + return new BigRational($this->numerator->abs(), $this->denominator, false);
342 + }
343 +
344 + /**
345 + * Returns the negated value of this BigRational.
346 + *
347 + * @return BigRational
348 + */
349 + public function negated() : BigRational
350 + {
351 + return new BigRational($this->numerator->negated(), $this->denominator, false);
352 + }
353 +
354 + /**
355 + * Returns the simplified value of this BigRational.
356 + *
357 + * @return BigRational
358 + */
359 + public function simplified() : BigRational
360 + {
361 + $gcd = $this->numerator->gcd($this->denominator);
362 +
363 + $numerator = $this->numerator->quotient($gcd);
364 + $denominator = $this->denominator->quotient($gcd);
365 +
366 + return new BigRational($numerator, $denominator, false);
367 + }
368 +
369 + /**
370 + * {@inheritdoc}
371 + */
372 + public function compareTo($that) : int
373 + {
374 + return $this->minus($that)->getSign();
375 + }
376 +
377 + /**
378 + * {@inheritdoc}
379 + */
380 + public function getSign() : int
381 + {
382 + return $this->numerator->getSign();
383 + }
384 +
385 + /**
386 + * {@inheritdoc}
387 + */
388 + public function toBigInteger() : BigInteger
389 + {
390 + $simplified = $this->simplified();
391 +
392 + if (! $simplified->denominator->isEqualTo(1)) {
393 + throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.');
394 + }
395 +
396 + return $simplified->numerator;
397 + }
398 +
399 + /**
400 + * {@inheritdoc}
401 + */
402 + public function toBigDecimal() : BigDecimal
403 + {
404 + return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator);
405 + }
406 +
407 + /**
408 + * {@inheritdoc}
409 + */
410 + public function toBigRational() : BigRational
411 + {
412 + return $this;
413 + }
414 +
415 + /**
416 + * {@inheritdoc}
417 + */
418 + public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal
419 + {
420 + return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode);
421 + }
422 +
423 + /**
424 + * {@inheritdoc}
425 + */
426 + public function toInt() : int
427 + {
428 + return $this->toBigInteger()->toInt();
429 + }
430 +
431 + /**
432 + * {@inheritdoc}
433 + */
434 + public function toFloat() : float
435 + {
436 + return $this->numerator->toFloat() / $this->denominator->toFloat();
437 + }
438 +
439 + /**
440 + * {@inheritdoc}
441 + */
442 + public function __toString() : string
443 + {
444 + $numerator = (string) $this->numerator;
445 + $denominator = (string) $this->denominator;
446 +
447 + if ($denominator === '1') {
448 + return $numerator;
449 + }
450 +
451 + return $this->numerator . '/' . $this->denominator;
452 + }
453 +
454 + /**
455 + * This method is required for serializing the object and SHOULD NOT be accessed directly.
456 + *
457 + * @internal
458 + *
459 + * @return array{numerator: BigInteger, denominator: BigInteger}
460 + */
461 + public function __serialize(): array
462 + {
463 + return ['numerator' => $this->numerator, 'denominator' => $this->denominator];
464 + }
465 +
466 + /**
467 + * This method is only here to allow unserializing the object and cannot be accessed directly.
468 + *
469 + * @internal
470 + * @psalm-suppress RedundantPropertyInitializationCheck
471 + *
472 + * @param array{numerator: BigInteger, denominator: BigInteger} $data
473 + *
474 + * @return void
475 + *
476 + * @throws \LogicException
477 + */
478 + public function __unserialize(array $data): void
479 + {
480 + if (isset($this->numerator)) {
481 + throw new \LogicException('__unserialize() is an internal function, it must not be called directly.');
482 + }
483 +
484 + $this->numerator = $data['numerator'];
485 + $this->denominator = $data['denominator'];
486 + }
487 +
488 + /**
489 + * This method is required by interface Serializable and SHOULD NOT be accessed directly.
490 + *
491 + * @internal
492 + *
493 + * @return string
494 + */
495 + public function serialize() : string
496 + {
497 + return $this->numerator . '/' . $this->denominator;
498 + }
499 +
500 + /**
501 + * This method is only here to implement interface Serializable and cannot be accessed directly.
502 + *
503 + * @internal
504 + * @psalm-suppress RedundantPropertyInitializationCheck
505 + *
506 + * @param string $value
507 + *
508 + * @return void
509 + *
510 + * @throws \LogicException
511 + */
512 + public function unserialize($value) : void
513 + {
514 + if (isset($this->numerator)) {
515 + throw new \LogicException('unserialize() is an internal function, it must not be called directly.');
516 + }
517 +
518 + [$numerator, $denominator] = \explode('/', $value);
519 +
520 + $this->numerator = BigInteger::of($numerator);
521 + $this->denominator = BigInteger::of($denominator);
522 + }
523 + }
524 +