This repository was archived by the owner on Jan 18, 2022. It is now read-only.
File tree Expand file tree Collapse file tree 1 file changed +26
-10
lines changed
src/main/java/org/javamoney/moneta Expand file tree Collapse file tree 1 file changed +26
-10
lines changed Original file line number Diff line number Diff line change @@ -453,18 +453,34 @@ private long multiplyExact(long num1, long num2) {
453453 if (num1 ==0 || num2 ==0 ){
454454 return 0 ;
455455 }
456- boolean pos = num1 >0 && num2 >0 ;
457- boolean neg = num1 <0 && num2 <0 ;
456+
457+ // Hacker's Delight,
458+ int leadingZeros =
459+ Long .numberOfLeadingZeros (num1 ) +
460+ Long .numberOfLeadingZeros (~num1 ) +
461+ Long .numberOfLeadingZeros (num2 ) +
462+ Long .numberOfLeadingZeros (~num2 );
463+
464+ if (leadingZeros > Long .SIZE + 1 ) {
465+ // in this case, an overflow is impossible
466+ return num1 * num2 ;
467+ }
468+
469+ if (leadingZeros < Long .SIZE ){
470+ if (Long .signum (num1 )*Long .signum (num2 ) > 0 ){
471+ throw new ArithmeticException ("Long evaluation positive overflow." );
472+ } else {
473+ throw new ArithmeticException ("Long evaluation negative overflow." );
474+ }
475+ }
476+
458477 long exact = num1 * num2 ;
459- if (pos && exact <=0 ){
460- throw new ArithmeticException ("Long evaluation positive overflow." );
461- }
462- if (neg && exact <=0 ){
463- throw new ArithmeticException ("Long evaluation negative overflow." );
464- }
465- if (!neg && !pos && exact >=0 ){
466- throw new ArithmeticException ("Long negative overflow." );
478+
479+ // very expensive - this check is only executed in special cases
480+ if ( num1 != 0 && exact / num1 != num2 ) {
481+ throw new ArithmeticException ("overflow" );
467482 }
483+
468484 return exact ;
469485 }
470486
You can’t perform that action at this time.
0 commit comments