@@ -163,8 +163,14 @@ long addLong(long left, long right) {
163
163
}
164
164
165
165
@ Specialization
166
- PInt addPInt (long left , long right ) {
167
- return factory ().createInt (op (PInt .longToBigInteger (left ), PInt .longToBigInteger (right )));
166
+ Object addLongWithOverflow (long x , long y ) {
167
+ /* Inlined version of Math.addExact(x, y) with BigInteger fallback. */
168
+ long r = x + y ;
169
+ // HD 2-12 Overflow iff both arguments have the opposite sign of the result
170
+ if (((x ^ r ) & (y ^ r )) < 0 ) {
171
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
172
+ }
173
+ return r ;
168
174
}
169
175
170
176
@ Specialization
@@ -220,8 +226,15 @@ long doLL(long x, long y) throws ArithmeticException {
220
226
}
221
227
222
228
@ Specialization
223
- PInt doLLOvf (long x , long y ) {
224
- return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
229
+ Object doLongWithOverflow (long x , long y ) {
230
+ /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */
231
+ long r = x - y ;
232
+ // HD 2-12 Overflow iff the arguments have different signs and
233
+ // the sign of the result is different than the sign of x
234
+ if (((x ^ y ) & (x ^ r )) < 0 ) {
235
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
236
+ }
237
+ return r ;
225
238
}
226
239
227
240
@ Specialization
@@ -272,8 +285,15 @@ long doLL(long y, long x) throws ArithmeticException {
272
285
}
273
286
274
287
@ Specialization
275
- PInt doLLOvf (long y , long x ) {
276
- return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
288
+ Object doLongWithOverflow (long y , long x ) {
289
+ /* Inlined version of Math.subtractExact(x, y) with BigInteger fallback. */
290
+ long r = x - y ;
291
+ // HD 2-12 Overflow iff the arguments have different signs and
292
+ // the sign of the result is different than the sign of x
293
+ if (((x ^ y ) & (x ^ r )) < 0 ) {
294
+ return factory ().createInt (op (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
295
+ }
296
+ return r ;
277
297
}
278
298
279
299
@ Specialization
@@ -642,17 +662,21 @@ long doLL(long x, long y) {
642
662
}
643
663
644
664
@ Specialization
645
- PInt doLLOvf (long x , long y ) {
665
+ Object doLongWithOverflow (long x , long y ) {
666
+ /* Inlined version of Math.multiplyExact(x, y) with BigInteger fallback. */
646
667
long r = x * y ;
647
668
long ax = Math .abs (x );
648
669
long ay = Math .abs (y );
649
670
if (((ax | ay ) >>> 31 != 0 )) {
650
- int leadingZeros = Long .numberOfLeadingZeros (ax ) + Long .numberOfLeadingZeros (ay );
651
- if (leadingZeros < 66 ) {
671
+ // Some bits greater than 2^31 that might cause overflow
672
+ // Check the result using the divide operator
673
+ // and check for the special case of Long.MIN_VALUE * -1
674
+ if (((y != 0 ) && (r / y != x )) ||
675
+ (x == Long .MIN_VALUE && y == -1 )) {
652
676
return factory ().createInt (mul (PInt .longToBigInteger (x ), PInt .longToBigInteger (y )));
653
677
}
654
678
}
655
- return factory (). createInt ( r ) ;
679
+ return r ;
656
680
}
657
681
658
682
@ Specialization (guards = "right == 0" )
0 commit comments