Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/tutor-pro/vendor/brick/math/src/BigRational.php
Keine Baseline-Datei – Diff nur gegen leer.
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
+