Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit 69a3038

Browse files
author
buchholz
committed
insert Hacker's Delight checks
1 parent 5059cd9 commit 69a3038

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/main/java/org/javamoney/moneta/FastMoney.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff 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

0 commit comments

Comments
 (0)