insaf021 opened a new pull request, #341:
URL: https://github.com/apache/commons-math/pull/341
Observed on master with a 20 digit DfpField:
field.newDfp("1e999999") -> 1.0000000000000000000e999999
(finite, FLAG_OVERFLOW set)
field.newDfp("1e999999").multiply(one) -> Infinity
field.newDfp("1e2147483648") -> finite tiny value,
lessThan(one) is true
field.newDfp("1e2147483648").toString() never returns:
"main" prio=5 RUNNABLE
at
org.apache.commons.math4.legacy.core.dfp.Dfp.dfp2sci(Dfp.java:2143)
at
org.apache.commons.math4.legacy.core.dfp.Dfp.toString(Dfp.java:2072)
The string constructor discards the flag returned by `round()`. Every
arithmetic operation passes that flag through `dotrap`, which turns an exponent
above MAX_EXP into infinity and one below the gradual underflow range into
zero, so a parsed value can break an invariant the rest of the class relies on
and disagree with any operation applied to it. The exponent digits are also
accumulated in an int with no bound, so "1e2147483648" wraps negative;
`dfp2sci` then computes `e == Integer.MIN_VALUE`, `ae = -e` stays negative and
`while (p > ae)` spins forever once `p` reaches 0.
The fix stays in the constructor: stop accumulating exponent digits once the
value is past anything representable, store a zero mantissa with a zero
exponent as `add` does, and hand the `round()` flag to `dotrap`, copying the
trapped result back the way the double constructor already does. Values inside
the representable range, including gradual underflow, are unchanged.
Two existing tests ("Next After #14" in DfpTest and DfpDecTest) parsed
`9.99...e131078`, which is beyond the largest finite value `9.99...e131071` and
only came out finite because of this bug; the literal is corrected to e131071
and the test still exercises the overflow on `nextAfter`. The new DfpTest case
fails on master at its first assertion. `mvn -pl commons-math-legacy-core
install` passes on JDK 21 (checkstyle, SpotBugs, PMD, 291 tests), and the Dfp
based tests in commons-math-legacy pass against the patched module.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]