Skip to content

Commit 94637e4

Browse files
trptcolinstuarthalloway
authored andcommitted
Make math commutative/correct for Long/MIN_VALUE
Signed-off-by: Stuart Halloway <stu@thinkrelevance.com>
1 parent b1fd40a commit 94637e4

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

src/jvm/clojure/lang/BigInt.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ public BigInt add(BigInt y) {
144144
public BigInt multiply(BigInt y) {
145145
if ((bipart == null) && (y.bipart == null)) {
146146
long ret = lpart * y.lpart;
147-
if (y.lpart == 0 || ret / y.lpart == lpart)
147+
if (y.lpart == 0 ||
148+
(ret / y.lpart == lpart && lpart != Long.MIN_VALUE))
148149
return BigInt.valueOf(ret);
149150
}
150151
return BigInt.fromBigInteger(this.toBigInteger().multiply(y.toBigInteger()));

src/jvm/clojure/lang/Numbers.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,8 @@ final public Number multiply(Number x, Number y){
444444

445445
final public Number multiplyP(Number x, Number y){
446446
long lx = x.longValue(), ly = y.longValue();
447+
if (lx == Long.MIN_VALUE && ly < 0)
448+
return BIGINT_OPS.multiply(x, y);
447449
long ret = lx * ly;
448450
if (ly != 0 && ret/ly != lx)
449451
return BIGINT_OPS.multiply(x, y);
@@ -1747,13 +1749,17 @@ static public Number decP(long x){
17471749

17481750

17491751
static public long multiply(long x, long y){
1752+
if (x == Long.MIN_VALUE && y < 0)
1753+
return throwIntOverflow();
17501754
long ret = x * y;
17511755
if (y != 0 && ret/y != x)
17521756
return throwIntOverflow();
17531757
return ret;
17541758
}
17551759

17561760
static public Number multiplyP(long x, long y){
1761+
if (x == Long.MIN_VALUE && y < 0)
1762+
return multiplyP((Number)x,(Number)y);
17571763
long ret = x * y;
17581764
if (y != 0 && ret/y != x)
17591765
return multiplyP((Number)x,(Number)y);

test/clojure/test_clojure/numbers.clj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,17 @@
214214

215215
(is (> (* 3 (int (/ Integer/MAX_VALUE 2.0))) Integer/MAX_VALUE)) ) ; no overflow
216216

217+
(deftest test-multiply-longs-at-edge
218+
(are [x] (= x 9223372036854775808N)
219+
(*' -1 Long/MIN_VALUE)
220+
(*' Long/MIN_VALUE -1)
221+
(* -1N Long/MIN_VALUE)
222+
(* Long/MIN_VALUE -1N)
223+
(* -1 (bigint Long/MIN_VALUE))
224+
(* (bigint Long/MIN_VALUE) -1))
225+
(is (thrown? ArithmeticException (* Long/MIN_VALUE -1)))
226+
(is (thrown? ArithmeticException (* -1 Long/MIN_VALUE))))
227+
217228
(deftest test-ratios-simplify-to-ints-where-appropriate
218229
(testing "negative denominator (assembla #275)"
219230
(is (integer? (/ 1 -1/2)))

0 commit comments

Comments
 (0)