Multiplication overflow issues around Long/MIN_VALUE

Description

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)

Environment

None

Attachments

1

Activity

Show:

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.

Completed

Details

Assignee

Reporter

Labels

Approval

Ok

Patch

Code and Test

Priority

Fix versions

Created June 21, 2013 at 6:37 PM
Updated November 23, 2013 at 1:06 AM
Resolved November 23, 2013 at 1:06 AM