Skip to content

Commit

Permalink
Merge pull request jruby#8523 from headius/avoid_multiplyexact_exception
Browse files Browse the repository at this point in the history
Revert multiply to use non-intrinsic exactness checks
  • Loading branch information
headius authored Jan 10, 2025
2 parents c37beff + b6f3b05 commit 42197f4
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import java.math.BigInteger;

import org.jcodings.specific.USASCIIEncoding;
import org.jruby.RubyEnumerator.SizeFn;
import org.jruby.compiler.Constantizable;
import org.jruby.runtime.Block;
import org.jruby.runtime.CallSite;
Expand Down Expand Up @@ -603,11 +602,21 @@ private IRubyObject multiplyOther(ThreadContext context, IRubyObject other) {
@Override
public IRubyObject op_mul(ThreadContext context, long other) {
Ruby runtime = context.runtime;
try {
return newFixnum(runtime, Math.multiplyExact(value, other));
} catch (ArithmeticException ae) {
return RubyBignum.newBignum(runtime, value).op_mul(context, other);

long value = this.value;
long result = value * other;

if (other == 0 // result is zero
|| ((Math.abs(value) | Math.abs(other)) >>> 31 == 0) // factors are both int32 range
|| (result / other == value && (value != Long.MIN_VALUE || other != -1)) // division produces value
) {
return newFixnum(runtime, result);
}

// overflow, use Bignum
BigInteger valueBig = BigInteger.valueOf(value);
BigInteger otherBig = BigInteger.valueOf(other);
return RubyBignum.newBignum(runtime, valueBig.multiply(otherBig));
}

public IRubyObject op_mul(ThreadContext context, double other) {
Expand Down

0 comments on commit 42197f4

Please sign in to comment.