Multiplication overflow issues around Long/MIN_VALUE
Description
Environment
Attachments
Activity
Rich Hickey November 22, 2013 at 4:14 PM
missed the ' earlier
Colin Jones November 22, 2013 at 2:14 PM
Rich, can you clarify? My understanding is that *' is an auto-promoting operation. For instance, in 1.5.1, *' auto-promotes in the positive direction:
user=> (*' Long/MAX_VALUE Long/MAX_VALUE)
85070591730234615847396907784232501249N
and in the negative:
user=> (*' Long/MIN_VALUE -2)
18446744073709551616N
The only outlier is the one addressed in this ticket. Am I missing something? What should the result be here if not the one given by this patch?
Rich Hickey November 22, 2013 at 1:28 PM
user=> (*' Long/MIN_VALUE -1)
9223372036854775808N
Is wrong - there should be no coercion, this is an overflowing operation.
Andy Fingerhut June 25, 2013 at 5:06 PM
I have created for the corresponding issues with / and quot with these arguments. I think that Long/MIN_VALUE and -1 should be the only arguments that cause problems for multiplication overflow detection, too, since it is based upon division, and I give some reasons in why I believe these are the only arguments that give the numerically wrong answer for the Java division operator / on longs.
Colin Jones June 21, 2013 at 7:54 PM
I don't have a proof, just a half-hour or so of digging for an alternate case (found none), plus taking a look at what Guava does in checkedMultiply: https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/math/LongMath.java#522
I didn't do the leading zeros optimization they're doing to avoid even the division in the overflow check we already have; that felt like a bigger change, and not one that impacts correctness.
Long story short (ha!), there are several related issues where overflow checking doesn't work correctly with Long/MIN_VALUE. The cause of this missed check is that in Java, these both pass:
This causes the following results in Clojure that do not match their siblings where the order of operands is switched:
Mailing list discussion here: https://groups.google.com/d/msg/clojure-dev/o1QGR1QK70M/A1KykR9OQqwJ
Patch: min_value_multiplication.diff
Approach: Modifies BigInt.multiply() and multiply/multiplyP in Numbers to take into account Long.MIN_VALUE.
After:
Screened by: Alex Miller (should also include CLJ-1225, CLJ-1253, CLJ-1254)