2
2
3
3
namespace Litipk \BigNumbers ;
4
4
5
+ use Litipk \BigNumbers \InfiniteDecimal as InfiniteDecimal ;
6
+
5
7
use Litipk \Exceptions \NotImplementedException as NotImplementedException ;
6
8
use Litipk \Exceptions \InvalidArgumentTypeException as InvalidArgumentTypeException ;
7
9
10
12
*
11
13
* @author Andreu Correa Casablanca <[email protected] >
12
14
*/
13
- final class Decimal
15
+ class Decimal
14
16
{
15
- /**
16
- * Single instance of "Positive Infinite"
17
- * @var Decimal
18
- */
19
- private static $ pInf = null ;
20
-
21
- /**
22
- * Single instance of "Negative Infinite"
23
- * @var Decimal
24
- */
25
- private static $ nInf = null ;
26
-
27
17
/**
28
18
* Internal numeric value
29
19
* @var string
30
20
*/
31
- private $ value ;
21
+ protected $ value ;
32
22
33
23
/**
34
24
* Number of digits behind the point
@@ -61,11 +51,7 @@ private function __clone()
61
51
*/
62
52
public static function getPositiveInfinite ()
63
53
{
64
- if (self ::$ pInf === null ) {
65
- self ::$ pInf = new Decimal ('INF ' , 0 );
66
- }
67
-
68
- return self ::$ pInf ;
54
+ return InfiniteDecimal::getPositiveInfinite ();
69
55
}
70
56
71
57
/**
@@ -74,11 +60,7 @@ public static function getPositiveInfinite()
74
60
*/
75
61
public static function getNegativeInfinite ()
76
62
{
77
- if (self ::$ nInf === null ) {
78
- self ::$ nInf = new Decimal ('-INF ' , 0 );
79
- }
80
-
81
- return self ::$ nInf ;
63
+ return InfiniteDecimal::getNegativeInfinite ();
82
64
}
83
65
84
66
/**
@@ -147,9 +129,9 @@ public static function fromFloat($fltValue, $scale = null)
147
129
'$fltValue must be of type float '
148
130
);
149
131
} elseif ($ fltValue === INF ) {
150
- return Decimal ::getPositiveInfinite ();
132
+ return InfiniteDecimal ::getPositiveInfinite ();
151
133
} elseif ($ fltValue === -INF ) {
152
- return Decimal ::getNegativeInfinite ();
134
+ return InfiniteDecimal ::getNegativeInfinite ();
153
135
} elseif (is_nan ($ fltValue )) {
154
136
throw new \DomainException (
155
137
"To ensure consistency, this class doesn't handle NaN objects. "
@@ -269,15 +251,7 @@ public function add(Decimal $b, $scale = null)
269
251
{
270
252
self ::paramsValidation ($ b , $ scale );
271
253
272
- if ($ this ->isInfinite ()) {
273
- if (!$ b ->isInfinite ()) {
274
- return $ this ;
275
- } elseif ($ this ->hasSameSign ($ b )) {
276
- return $ this ;
277
- } else { // elseif ($this->isPositive() && $b->isNegative || $this->isNegative() && $b->isPositive()) {
278
- throw new \DomainException ("Infinite numbers with opposite signs can't be added " );
279
- }
280
- } elseif ($ b ->isInfinite ()) {
254
+ if ($ b ->isInfinite ()) {
281
255
return $ b ;
282
256
}
283
257
@@ -297,15 +271,7 @@ public function sub(Decimal $b, $scale = null)
297
271
{
298
272
self ::paramsValidation ($ b , $ scale );
299
273
300
- if ($ this ->isInfinite ()) {
301
- if (!$ b ->isInfinite ()) {
302
- return $ this ;
303
- } elseif (!$ this ->hasSameSign ($ b )) {
304
- return $ this ;
305
- } else { // elseif () {
306
- throw new \DomainException ("Infinite numbers with the same sign can't be subtracted " );
307
- }
308
- } elseif ($ b ->isInfinite ()) {
274
+ if ($ b ->isInfinite ()) {
309
275
return $ b ->additiveInverse ();
310
276
}
311
277
@@ -325,18 +291,10 @@ public function mul(Decimal $b, $scale = null)
325
291
{
326
292
self ::paramsValidation ($ b , $ scale );
327
293
328
- if ($ this -> isInfinite () || $ b ->isZero ()) {
294
+ if ($ b ->isInfinite ()) {
329
295
return $ b ->mul ($ this );
330
- } elseif ($ this ->isZero () && $ b ->isInfinite ()) {
331
- throw new \DomainException ("Zero multiplied by infinite is not allowed. " );
332
- } elseif ($ this ->isZero () && !$ b ->isInfinite ()) {
296
+ } elseif ($ b ->isZero ()) {
333
297
return Decimal::fromInteger (0 , $ scale );
334
- } elseif ($ b ->isInfinite ()) {
335
- if ($ this ->hasSameSign ($ b )) {
336
- return self ::getPositiveInfinite ();
337
- } else { // elseif ($this->isPositive() && $b->isNegative() || $this->isNegative() && $b->isPositive()) {
338
- return self ::getNegativeInfinite ();
339
- }
340
298
}
341
299
342
300
return self ::fromString (
@@ -363,16 +321,6 @@ public function div(Decimal $b, $scale = null)
363
321
throw new \DomainException ("Division by zero is not allowed. " );
364
322
} elseif ($ this ->isZero ()) {
365
323
return self ::fromDecimal ($ this , $ scale );
366
- } elseif ($ this ->isInfinite ()) {
367
-
368
- if ($ b ->isInfinite ()) {
369
- throw new \DomainException ("Infinite divided by Infinite is not allowed. " );
370
- } elseif ($ b ->isPositive ()) {
371
- return $ this ;
372
- } else { //if ($b->isNegative()) {
373
- return $ this ->additiveInverse ();
374
- }
375
-
376
324
} elseif ($ b ->isInfinite ()) {
377
325
return Decimal::fromInteger (0 , $ scale );
378
326
} else {
@@ -417,8 +365,6 @@ public function sqrt($scale = null)
417
365
);
418
366
} elseif ($ this ->isZero ()) {
419
367
return Decimal::fromDecimal ($ this , $ scale );
420
- } elseif ($ this ->isInfinite ()) {
421
- return $ this ;
422
368
}
423
369
424
370
$ sqrt_scale = ($ scale !== null ? $ scale : $ this ->scale );
@@ -494,12 +440,10 @@ public function log10($scale = null)
494
440
{
495
441
if ($ this ->isNegative ()) {
496
442
throw new \DomainException (
497
- "Decimal can't handle logarithms of negative numbers (it's only for real numbers) "
443
+ "Decimal can't handle logarithms of negative numbers (it's only for real numbers). "
498
444
);
499
445
} elseif ($ this ->isZero ()) {
500
- return Decimal::getNegativeInfinite ();
501
- } elseif ($ this ->isInfinite ()) {
502
- return $ this ;
446
+ return InfiniteDecimal::getNegativeInfinite ();
503
447
}
504
448
505
449
return self ::fromString (
@@ -513,10 +457,6 @@ public function log10($scale = null)
513
457
*/
514
458
public function isZero ($ scale = null )
515
459
{
516
- if ($ this ->isInfinite ()) {
517
- return false ;
518
- }
519
-
520
460
$ cmp_scale = $ scale !== null ? $ scale : $ this ->scale ;
521
461
522
462
return (bccomp (self ::innerRound ($ this ->value , $ cmp_scale ), '0 ' , $ cmp_scale ) === 0 );
@@ -543,7 +483,7 @@ public function isNegative()
543
483
*/
544
484
public function isInfinite ()
545
485
{
546
- return ( $ this === self :: $ pInf || $ this === self :: $ nInf ) ;
486
+ return false ;
547
487
}
548
488
549
489
/**
@@ -558,7 +498,7 @@ public function equals(Decimal $b, $scale = null)
558
498
559
499
if ($ this === $ b ) {
560
500
return true ;
561
- } elseif ($ this ->isInfinite ()) {
501
+ } elseif ($ b ->isInfinite ()) {
562
502
return false ;
563
503
} else {
564
504
$ cmp_scale = $ scale !== null ? $ scale : max ($ this ->scale , $ b ->scale );
@@ -585,10 +525,8 @@ public function comp(Decimal $b, $scale = null)
585
525
586
526
if ($ this === $ b ) {
587
527
return 0 ;
588
- } elseif ($ this === self ::getPositiveInfinite () || $ b === self ::getNegativeInfinite ()) {
589
- return 1 ;
590
- } elseif ($ this === self ::getNegativeInfinite () || $ b === self ::getPositiveInfinite ()) {
591
- return -1 ;
528
+ } elseif ($ b ->isInfinite ()) {
529
+ return -$ b ->comp ($ this );
592
530
}
593
531
594
532
return bccomp (
@@ -606,13 +544,7 @@ public function additiveInverse()
606
544
{
607
545
if ($ this ->isZero ()) {
608
546
return $ this ;
609
- } elseif ($ this === self ::getPositiveInfinite ()) {
610
- return self ::$ nInf ;
611
- } elseif ($ this === self ::getNegativeInfinite ()) {
612
- return self ::$ pInf ;
613
- }
614
-
615
- if ($ this ->isNegative ()) {
547
+ } elseif ($ this ->isNegative ()) {
616
548
$ value = substr ($ this ->value , 1 );
617
549
} else { // if ($this->isPositive()) {
618
550
$ value = '- ' . $ this ->value ;
@@ -628,7 +560,7 @@ public function additiveInverse()
628
560
*/
629
561
public function round ($ scale = 0 )
630
562
{
631
- if ($ scale >= $ this ->scale || $ this -> isInfinite () ) {
563
+ if ($ scale >= $ this ->scale ) {
632
564
return $ this ;
633
565
}
634
566
@@ -798,7 +730,7 @@ private static function compute2NRoot($base, $index, $out_scale)
798
730
* @param mixed $value
799
731
* @param integer $scale
800
732
*/
801
- private static function paramsValidation ($ value , $ scale )
733
+ protected static function paramsValidation ($ value , $ scale )
802
734
{
803
735
if ($ value === null ) {
804
736
throw new \InvalidArgumentException ('$value must be a non null number ' );
0 commit comments