1212use Brick \Math \Exception \UnsupportedPlatformException ;
1313use Brick \Math \Internal \CalculatorRegistry ;
1414use Brick \Math \Internal \DecimalHelper ;
15+ use Brick \Math \Internal \SafeInt ;
1516use LogicException ;
1617use Override ;
1718
@@ -97,7 +98,7 @@ public static function ofUnscaledValue(BigNumber|int|string $value, int $scale =
9798
9899 if ($ scale < 0 ) {
99100 if ($ value !== '0 ' ) {
100- $ value .= str_repeat ('0 ' , - $ scale );
101+ $ value .= str_repeat ('0 ' , SafeInt:: neg ( $ scale) );
101102 }
102103 $ scale = 0 ;
103104 }
@@ -385,12 +386,14 @@ public function multipliedBy(BigNumber|int|string $that): BigDecimal
385386 return $ that ;
386387 }
387388
389+ /** @var non-negative-int $scale */
390+ $ scale = SafeInt::add ($ this ->scale , $ that ->scale );
391+
388392 if ($ this ->isZero () || $ that ->isZero ()) {
389- return new BigDecimal ('0 ' , $ this -> scale + $ that -> scale );
393+ return new BigDecimal ('0 ' , $ scale );
390394 }
391395
392396 $ value = CalculatorRegistry::get ()->mul ($ this ->value , $ that ->value );
393- $ scale = $ this ->scale + $ that ->scale ;
394397
395398 return new BigDecimal ($ value , $ scale );
396399 }
@@ -426,8 +429,8 @@ public function dividedBy(BigNumber|int|string $that, int $scale, RoundingMode $
426429 return $ this ;
427430 }
428431
429- $ p = $ this ->valueWithMinScale ($ that ->scale + $ scale );
430- $ q = $ that ->valueWithMinScale ($ this ->scale - $ scale );
432+ $ p = $ this ->valueWithMinScale (SafeInt:: add ( $ that ->scale , $ scale) );
433+ $ q = $ that ->valueWithMinScale (SafeInt:: sub ( $ this ->scale , $ scale) );
431434
432435 $ calculator = CalculatorRegistry::get ();
433436 $ result = $ calculator ->divRound ($ p , $ q , $ roundingMode );
@@ -508,7 +511,10 @@ public function power(int $exponent): BigDecimal
508511 throw InvalidArgumentException::negativeExponent ();
509512 }
510513
511- return new BigDecimal (CalculatorRegistry::get ()->pow ($ this ->value , $ exponent ), $ this ->scale * $ exponent );
514+ /** @var non-negative-int $scale */
515+ $ scale = SafeInt::mul ($ this ->scale , $ exponent );
516+
517+ return new BigDecimal (CalculatorRegistry::get ()->pow ($ this ->value , $ exponent ), $ scale );
512518 }
513519
514520 /**
@@ -658,14 +664,14 @@ public function sqrt(int $scale, RoundingMode $roundingMode = RoundingMode::Unne
658664
659665 if ($ inputScale % 2 !== 0 ) {
660666 $ value .= '0 ' ;
661- $ inputScale++ ;
667+ $ inputScale = SafeInt:: add ( $ inputScale , 1 ) ;
662668 }
663669
664670 $ calculator = CalculatorRegistry::get ();
665671
666672 // Keep one extra digit for rounding.
667- $ intermediateScale = max ($ scale , intdiv ($ inputScale , 2 )) + 1 ;
668- $ value .= str_repeat ('0 ' , 2 * $ intermediateScale - $ inputScale );
673+ $ intermediateScale = SafeInt:: add ( max ($ scale , intdiv ($ inputScale , 2 )), 1 ) ;
674+ $ value .= str_repeat ('0 ' , SafeInt:: sub (SafeInt:: mul ( 2 , $ intermediateScale), $ inputScale) );
669675
670676 $ sqrt = $ calculator ->sqrt ($ value );
671677 $ isExact = $ calculator ->mul ($ sqrt , $ sqrt ) === $ value ;
@@ -710,10 +716,13 @@ public function withPointMovedLeft(int $places): BigDecimal
710716 }
711717
712718 if ($ places < 0 ) {
713- return $ this ->withPointMovedRight (- $ places );
719+ return $ this ->withPointMovedRight (SafeInt:: neg ( $ places) );
714720 }
715721
716- return new BigDecimal ($ this ->value , $ this ->scale + $ places );
722+ /** @var non-negative-int $scale */
723+ $ scale = SafeInt::add ($ this ->scale , $ places );
724+
725+ return new BigDecimal ($ this ->value , $ scale );
717726 }
718727
719728 /**
@@ -730,15 +739,15 @@ public function withPointMovedRight(int $places): BigDecimal
730739 }
731740
732741 if ($ places < 0 ) {
733- return $ this ->withPointMovedLeft (- $ places );
742+ return $ this ->withPointMovedLeft (SafeInt:: neg ( $ places) );
734743 }
735744
736745 $ value = $ this ->value ;
737- $ scale = $ this ->scale - $ places ;
746+ $ scale = SafeInt:: sub ( $ this ->scale , $ places) ;
738747
739748 if ($ scale < 0 ) {
740749 if ($ value !== '0 ' ) {
741- $ value .= str_repeat ('0 ' , - $ scale );
750+ $ value .= str_repeat ('0 ' , SafeInt:: neg ( $ scale) );
742751 }
743752 $ scale = 0 ;
744753 }
0 commit comments