Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 18f8065401b8
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c87b6c8c18dd
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Oct 18, 2017

  1. Overflow cases for ** from MRI #13242.

    See https://bugs.ruby-lang.org/issues/13242
    
    Note that this does not appear to let us pass the related test,
    which runs for a long time (>1min on my machine) to eventually
    produce a Rational instead of infinity.
    headius committed Oct 18, 2017
    Copy the full SHA
    61bf72e View commit details
  2. Copy the full SHA
    c87b6c8 View commit details
Showing with 20 additions and 6 deletions.
  1. +8 −0 core/src/main/java/org/jruby/RubyRational.java
  2. +11 −6 core/src/main/java/org/jruby/util/Numeric.java
  3. +1 −0 test/mri/excludes/Rational_Test.rb
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/RubyRational.java
Original file line number Diff line number Diff line change
@@ -642,6 +642,14 @@ public IRubyObject op_expt(ThreadContext context, IRubyObject other) {
} else {
tnum = tden = RubyFixnum.one(runtime);
}
if (num instanceof RubyFloat) { /* infinity due to overflow */
if (den instanceof RubyFloat) return RubyNumeric.dbl2num(runtime, Double.NaN);
return num;
}
if (den instanceof RubyFloat) { /* infinity due to overflow */
num = RubyFixnum.zero(runtime);
den = RubyFixnum.one(runtime);
}
return RubyRational.newRational(context, getMetaClass(), tnum, tden);
} else if (other instanceof RubyFloat || other instanceof RubyRational) {
return f_expt(context, f_to_f(context, this), other);
17 changes: 11 additions & 6 deletions core/src/main/java/org/jruby/util/Numeric.java
Original file line number Diff line number Diff line change
@@ -500,25 +500,30 @@ public static IRubyObject int_pow(ThreadContext context, long x, long y) {
do {
while (y % 2 == 0) {
if (!fitSqrtLong(x)) {
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;
return bignumIntPow(context, x, y, neg, z, runtime);
}
x *= x;
y >>= 1;
}

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;
return bignumIntPow(context, x, y, neg, z, runtime);
}
z = x * z;
} while(--y != 0);
if (neg) z = -z;
return RubyFixnum.newFixnum(runtime, z);
}

// MRI: int_pow, bignum labeled portion
private static IRubyObject bignumIntPow(ThreadContext context, long x, long y, boolean neg, long z, Ruby runtime) {
IRubyObject v = RubyBignum.newBignum(runtime, RubyBignum.fix2big(RubyFixnum.newFixnum(runtime, x))).op_pow(context, RubyFixnum.newFixnum(runtime, y));
if (v instanceof RubyFloat) /* infinity due to overflow */
return v;
if (z != 1) v = RubyBignum.newBignum(runtime, RubyBignum.fix2big(RubyFixnum.newFixnum(runtime, neg ? -z : z))).op_mul19(context, v);
return v;
}

public static boolean multiplyOverflows(long a, long b) {
return a == 0 ? false :
a == -1 ? b < -Long.MAX_VALUE :
1 change: 1 addition & 0 deletions test/mri/excludes/Rational_Test.rb
Original file line number Diff line number Diff line change
@@ -5,4 +5,5 @@
exclude :test_marshal, "needs investigation"
exclude :test_power_of_0, "needs investigation"
exclude :test_power_of_1_and_minus_1, "needs investigation"
exclude :test_power_overflow, "runs long eventually fails, see https://bugs.ruby-lang.org/issues/13242"
exclude :test_ratsub, "needs investigation"