Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/main/java/org/apache/commons/lang3/math/Fraction.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ public static Fraction getFraction(double value) {
if (i == 25) {
throw new ArithmeticException("Unable to convert double to fraction");
}
return getReducedFraction((numer0 + wholeNumber * denom0) * sign, denom0);
// wholeNumber can be up to Integer.MAX_VALUE while denom0 > 1 for any non-integer value,
// so the int product overflows for values near the limit; check it instead of wrapping silently.
final int numerator = Math.addExact(numer0, mulAndCheck(wholeNumber, denom0));
return getReducedFraction(numerator * sign, denom0);
}

/**
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/org/apache/commons/lang3/math/FractionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ void testFactory_double() {
assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Double.POSITIVE_INFINITY));
assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Double.NEGATIVE_INFINITY));
assertThrows(ArithmeticException.class, () -> Fraction.getFraction((double) Integer.MAX_VALUE + 1));
// near Integer.MAX_VALUE with a fractional part: numerator overflows an int, so it must throw
// rather than silently return a wrong fraction (previously -3/2 and -2147483647/2 respectively)
assertThrows(ArithmeticException.class, () -> Fraction.getFraction(2147483646.5d));
assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1073741824.5d));

// zero
Fraction f = Fraction.getFraction(0.0d);
Expand Down
Loading