Skip to content

Commit

Permalink
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions core/src/main/java/org/jruby/util/Numeric.java
Original file line number Diff line number Diff line change
@@ -507,19 +507,25 @@ public static IRubyObject int_pow(ThreadContext context, long x, long y) {
y >>= 1;
}

BigInteger bigX = BigInteger.valueOf(x);
BigInteger bigXZ = bigX.multiply(bigX);
if (bigXZ.divide(bigX).longValue() != z) {
if (multiplyOverflows(x, z)) {
IRubyObject v = RubyBignum.newBignum(runtime, RubyBignum.fix2big(RubyFixnum.newFixnum(runtime, x))).op_pow(context, RubyFixnum.newFixnum(runtime, y));
if (z != 1) v = RubyBignum.newBignum(runtime, RubyBignum.fix2big(RubyFixnum.newFixnum(runtime, neg ? -z : z))).op_mul19(context, v);
return v;
}
z = bigXZ.longValue();
z = x * z;
} while(--y != 0);
if (neg) z = -z;
return RubyFixnum.newFixnum(runtime, z);
}

public static boolean multiplyOverflows(long a, long b) {
return a == 0 ? false :
a == -1 ? b < -Long.MAX_VALUE :
a > 0 ? (b > 0 ? Long.MAX_VALUE / a < b : Long.MIN_VALUE / a > b) :
(b > 0 ? Long.MIN_VALUE / a < b : Long.MAX_VALUE / a > b);

This comment has been minimized.

Copy link
@eregon

eregon Apr 22, 2016

Member

Too bad it's Java 7 and we can't use multiplyExact.

}


public static boolean k_exact_p(IRubyObject x) {
return !(x instanceof RubyFloat);
}

3 comments on commit 1e2c561

@headius
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably could have a static boolean to check if we're on Java 8 and call invokeExact then, but I wonder how much it would interfere with optimization to add that branch. It should fold away in Hotspot.

@enebo
Copy link
Member Author

@enebo enebo commented on 1e2c561 Apr 22, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would multipleExact be faster at a cost? It raises an exception on overflow. So if you end up needing to promote you get the icky overhead with it.

Sorry, something went wrong.

@headius
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@enebo The ArithmeticException thrown does have exception + stack trace overhead, but only when you overflow. I'd have preferred a lightweight exception, but it may all inline together and eliminate the stack trace...I'm not sure.

Sorry, something went wrong.

Please sign in to comment.