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: 1e41a7ddf8b0
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0cd602d08299
Choose a head ref
  • 5 commits
  • 6 files changed
  • 1 contributor

Commits on Aug 8, 2017

  1. Copy the full SHA
    ee0e555 View commit details
  2. Copy the full SHA
    0fd90c0 View commit details
  3. Copy the full SHA
    07615cb View commit details
  4. Copy the full SHA
    562a1f9 View commit details
  5. Copy the full SHA
    0cd602d View commit details
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
@@ -158,6 +158,11 @@ public BigInteger getValue() {
@Override
public int signum() { return value.signum(); }

@Override
public RubyInteger negate() {
return RubyBignum.newBignum(getRuntime(), value.negate());
}

/* ================
* Utility Methods
* ================
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
@@ -184,6 +184,11 @@ public BigInteger getBigIntegerValue() {
@Override
public int signum() { return Long.signum(value); }

@Override
public RubyInteger negate() {
return RubyFixnum.newFixnum(getRuntime(), -value);
}

public static RubyFixnum newFixnum(Ruby runtime, long value) {
if (USE_CACHE && isInCacheRange(value)) {
return cachedFixnum(runtime, value);
12 changes: 12 additions & 0 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
@@ -109,6 +109,18 @@ protected RubyFloat toFloat() {

public int signum() { return getBigIntegerValue().signum(); }

public abstract RubyInteger negate() ;

@Override
public IRubyObject isNegative(ThreadContext context) {
return context.runtime.newBoolean(signum() < 0);
}

@Override
public IRubyObject isPositive(ThreadContext context) {
return context.runtime.newBoolean(signum() > 0);
}

/* ================
* Instance Methods
* ================
13 changes: 7 additions & 6 deletions core/src/main/java/org/jruby/RubyNumeric.java
Original file line number Diff line number Diff line change
@@ -722,8 +722,8 @@ public IRubyObject op_cmp(IRubyObject other) {
*/
@JRubyMethod(name = "eql?")
public IRubyObject eql_p(ThreadContext context, IRubyObject other) {
if (getClass() != other.getClass()) return getRuntime().getFalse();
return equalInternal(context, this, other) ? getRuntime().getTrue() : getRuntime().getFalse();
if (getClass() != other.getClass()) return context.runtime.getFalse();
return equalInternal(context, this, other) ? context.runtime.getTrue() : context.runtime.getFalse();
}

/** num_quo
@@ -852,7 +852,8 @@ public IRubyObject integer_p() {
*/
@JRubyMethod(name = "zero?")
public IRubyObject zero_p(ThreadContext context) {
return equalInternal(context, this, RubyFixnum.zero(getRuntime())) ? getRuntime().getTrue() : getRuntime().getFalse();
final Ruby runtime = context.runtime;
return equalInternal(context, this, RubyFixnum.zero(runtime)) ? runtime.getTrue() : runtime.getFalse();
}

/** num_nonzero_p
@@ -917,10 +918,8 @@ public IRubyObject step(ThreadContext context, IRubyObject[] args, Block block)
/** num_step_scan_args
*
*/

private IRubyObject[] scanStepArgs(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.runtime;

IRubyObject to = context.nil;
IRubyObject step = runtime.newFixnum(1);

@@ -1203,7 +1202,7 @@ public static double floatStepSize(double beg, double end, double unit, boolean
*/
protected final IRubyObject op_num_equal(ThreadContext context, IRubyObject other) {
// it won't hurt fixnums
if (this == other) return getRuntime().getTrue();
if (this == other) return context.runtime.getTrue();

return numFuncall(context, other, sites(context).op_equals, this);
}
@@ -1303,6 +1302,7 @@ public Object toJava(Class target) {
return JavaUtil.getNumericConverter(target).coerce(this, target);
}

@Deprecated // not-used
public static class InvalidIntegerException extends NumberFormatException {
private static final long serialVersionUID = 55019452543252148L;

@@ -1318,6 +1318,7 @@ public Throwable fillInStackTrace() {
}
}

@Deprecated // not-used
public static class NumberTooLargeException extends NumberFormatException {
private static final long serialVersionUID = -1835120694982699449L;
public NumberTooLargeException() {
87 changes: 48 additions & 39 deletions core/src/main/java/org/jruby/RubyRational.java
Original file line number Diff line number Diff line change
@@ -144,17 +144,21 @@ static RubyRational newRationalRaw(Ruby runtime, IRubyObject x) {
/** rb_rational_new1
*
*/
static IRubyObject newRationalCanonicalize(ThreadContext context, IRubyObject x) {
static IRubyObject newRationalCanonicalize(ThreadContext context, RubyInteger x) {
return newRationalCanonicalize(context, x, RubyFixnum.one(context.runtime));
}

/** rb_rational_new
*
*/
public static IRubyObject newRationalCanonicalize(ThreadContext context, IRubyObject x, IRubyObject y) {
public static IRubyObject newRationalCanonicalize(ThreadContext context, RubyInteger x, RubyInteger y) {
return canonicalizeInternal(context, context.runtime.getRational(), x, y);
}

public static IRubyObject newRationalCanonicalize(ThreadContext context, IRubyObject x, IRubyObject y) {
return canonicalizeInternal(context, context.runtime.getRational(), (RubyInteger) x, (RubyInteger) y);
}

public static IRubyObject newRationalCanonicalize(ThreadContext context, long x, long y) {
Ruby runtime = context.runtime;
return canonicalizeInternal(context, runtime.getRational(), runtime.newFixnum(x), runtime.newFixnum(y));
@@ -163,8 +167,7 @@ public static IRubyObject newRationalCanonicalize(ThreadContext context, long x,
/** f_rational_new2
*
*/
private static IRubyObject newRational(ThreadContext context, IRubyObject clazz, IRubyObject x, IRubyObject y) {
assert !(x instanceof RubyRational) && !(y instanceof RubyRational);
private static IRubyObject newRational(ThreadContext context, IRubyObject clazz, RubyInteger x, RubyInteger y) {
return canonicalizeInternal(context, clazz, x, y);
}

@@ -221,33 +224,36 @@ static void intCheck(ThreadContext context, IRubyObject num) {
/** nurat_int_value
*
*/
static IRubyObject intValue(ThreadContext context, IRubyObject num) {
static RubyInteger intValue(ThreadContext context, IRubyObject num) {
IRubyObject i;
if (( i = RubyInteger.toInteger(context, num) ) == null) {
throw context.runtime.newTypeError("can't convert " + num.getMetaClass().getName() + " into Rational");
}
return i;
return (RubyInteger) i;
}

/** nurat_s_canonicalize_internal
*
*/
private static IRubyObject canonicalizeInternal(ThreadContext context, IRubyObject clazz, IRubyObject num, IRubyObject den) {
// MRI: nurat_canonicalize, negation part
if (canonicalizeShouldNegate(context, num, den)) {
num = f_negate(context, num);
den = f_negate(context, den);
private static IRubyObject canonicalizeInternal(ThreadContext context, IRubyObject clazz, RubyInteger num, RubyInteger den) {
Ruby runtime = context.runtime;
final int res = den.signum();
if (res < 0) { // MRI: nurat_canonicalize, negation part (replacement)
num = num.negate();
den = den.negate();
} else if (res == 0) {
throw runtime.newZeroDivisionError();
}

IRubyObject gcd = f_gcd(context, num, den);
num = f_idiv(context, num, gcd);
den = f_idiv(context, den, gcd);
IRubyObject _num = f_idiv(context, num, gcd); // TODO use RubyInteger#fdiv
IRubyObject _den = f_idiv(context, den, gcd); // TODO use RubyInteger#fdiv

if (Numeric.CANON && canonicalization && f_one_p(context, den)) {
return num;
if (Numeric.CANON && canonicalization && f_one_p(context, _den)) {
return _num;
}

return new RubyRational(context.runtime, clazz, num, den);
return new RubyRational(context.runtime, clazz, _num, _den);
}

/** nurat_s_canonicalize_internal_no_reduce
@@ -294,17 +300,18 @@ public static IRubyObject newInstance(ThreadContext context, IRubyObject clazz,

// @JRubyMethod(name = "new", meta = true, visibility = Visibility.PRIVATE)
public static IRubyObject newInstance(ThreadContext context, IRubyObject clazz, IRubyObject num) {
num = intValue(context, num);
return canonicalizeInternal(context, clazz, num, RubyFixnum.one(context.runtime));
return canonicalizeInternal(context, clazz, intValue(context, num), RubyFixnum.one(context.runtime));
}

// @JRubyMethod(name = "new", meta = true, visibility = Visibility.PRIVATE)
public static IRubyObject newInstance(ThreadContext context, IRubyObject clazz, IRubyObject num, IRubyObject den) {
num = intValue(context, num);
den = intValue(context, den);
return canonicalizeInternal(context, clazz, num, den);
return canonicalizeInternal(context, clazz, intValue(context, num), intValue(context, den));
}


public static IRubyObject newInstance(ThreadContext context, RubyInteger num, RubyInteger den) {
return canonicalizeInternal(context, context.runtime.getRational(), num, den);
}

/** rb_Rational1
*
*/
@@ -666,13 +673,13 @@ public final IRubyObject op_expt(ThreadContext context, long other) {
}

private IRubyObject fix_expt(ThreadContext context, RubyInteger other, final int sign) {
final IRubyObject tnum, tden;
final RubyInteger tnum, tden;
if (sign > 0) { // other > 0
tnum = f_expt(context, num, other);
tden = f_expt(context, den, other);
tnum = (RubyInteger) f_expt(context, num, other);
tden = (RubyInteger) f_expt(context, den, other);
} else if (sign < 0) { // other < 0
tnum = f_expt(context, den, f_negate(context, other));
tden = f_expt(context, num, f_negate(context, other));
tnum = (RubyInteger) f_expt(context, den, f_negate(context, other));
tden = (RubyInteger) f_expt(context, num, f_negate(context, other));
} else { // other == 0
tnum = tden = RubyFixnum.one(context.runtime);
}
@@ -686,12 +693,14 @@ private IRubyObject fix_expt(ThreadContext context, RubyInteger other, final int
@Override
public IRubyObject op_cmp(ThreadContext context, IRubyObject other) {
if (other instanceof RubyFixnum || other instanceof RubyBignum) {
if (den instanceof RubyFixnum && ((RubyFixnum)den).getLongValue() == 1) return f_cmp(context, num, other);
if (den instanceof RubyFixnum && ((RubyFixnum) den).getLongValue() == 1) return f_cmp(context, num, other);
return f_cmp(context, this, RubyRational.newRationalBang(context, getMetaClass(), other));
} else if (other instanceof RubyFloat) {
}
if (other instanceof RubyFloat) {
return f_cmp(context, f_to_f(context, this), other);
} else if (other instanceof RubyRational) {
RubyRational otherRational = (RubyRational)other;
}
if (other instanceof RubyRational) {
RubyRational otherRational = (RubyRational) other;
final IRubyObject num1, num2;
if (num instanceof RubyFixnum && den instanceof RubyFixnum &&
otherRational.num instanceof RubyFixnum && otherRational.den instanceof RubyFixnum) {
@@ -910,7 +919,7 @@ private IRubyObject roundCommon(ThreadContext context, IRubyObject n, RoundingMo
}

if (!(n instanceof RubyInteger)) {
throw runtime.newTypeError(n, getRuntime().getInteger());
throw runtime.newTypeError(n, runtime.getInteger());
}

b = runtime.newFixnum(10).op_pow(context, n);
@@ -926,12 +935,12 @@ private IRubyObject roundCommon(ThreadContext context, IRubyObject n, RoundingMo
RubyClass metaClass = getMetaClass();
RubyFixnum one = RubyFixnum.one(runtime);
if (!(s instanceof RubyRational)) {
s = RubyRational.newRational(context, metaClass, s, one);
s = RubyRational.newRational(context, metaClass, (RubyInteger) s, one);
}

s = ((RubyRational) s).doRound(context, mode);

s = RubyRational.newRational(context, metaClass, s, one);
s = RubyRational.newRational(context, metaClass, (RubyInteger) s, one);
s = ((RubyRational) s).op_div(context, b);

if (s instanceof RubyRational && ((RubyInteger) n).op_cmp(context, one).convertToInteger().getLongValue() < 0) {
@@ -961,7 +970,7 @@ private IRubyObject doRound(ThreadContext context, RoundingMode mode) {
}

// MRI: nurat_round_half_down
private IRubyObject roundHalfDown(ThreadContext context) {
private RubyInteger roundHalfDown(ThreadContext context) {
Ruby runtime = context.runtime;

RubyInteger num = this.num, den = this.den;
@@ -985,7 +994,7 @@ private IRubyObject roundHalfDown(ThreadContext context) {
}

// MRI: nurat_round_half_even
private IRubyObject roundHalfEven(ThreadContext context) {
private RubyInteger roundHalfEven(ThreadContext context) {
Ruby runtime = context.runtime;

RubyInteger num = this.num, den = this.den;
@@ -1014,7 +1023,7 @@ private IRubyObject roundHalfEven(ThreadContext context) {
}

// MRI: nurat_round_half_up
private IRubyObject roundHalfUp(ThreadContext context) {
private RubyInteger roundHalfUp(ThreadContext context) {
Ruby runtime = context.runtime;

RubyInteger num = this.num, den = this.den;
@@ -1132,7 +1141,7 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
ary[1] = b;
IRubyObject[] ans = nurat_rationalize_internal(context, ary);

return newRational(context, this.metaClass, ans[0], ans[1]);
return newRational(context, this.metaClass, (RubyInteger) ans[0], (RubyInteger) ans[1]);
}

/** nurat_hash
@@ -1257,7 +1266,7 @@ static RubyArray str_to_r_internal(ThreadContext context, IRubyObject recv) {
IRubyObject ip = a.eltInternal(0);
IRubyObject fp = a.size() != 2 ? runtime.getNil() : a.eltInternal(1);

IRubyObject v = RubyRational.newRationalCanonicalize(context, f_to_i(context, ip));
IRubyObject v = RubyRational.newRationalCanonicalize(context, (RubyInteger) f_to_i(context, ip));

if (!fp.isNil()) {
bytes = fp.convertToString().getByteList();
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/util/Numeric.java
Original file line number Diff line number Diff line change
@@ -39,6 +39,8 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

import java.math.BigInteger;

public class Numeric {
public static final boolean CANON = true;

@@ -61,6 +63,12 @@ public static IRubyObject f_cmp(ThreadContext context, IRubyObject x, IRubyObjec
if (c < 0) return RubyFixnum.minus_one(context.runtime); // x < y
return RubyFixnum.zero(context.runtime);
}
if (x instanceof RubyInteger && y instanceof RubyInteger) { // RubyBignum || RubyFixnum
BigInteger c = ((RubyInteger) x).getBigIntegerValue().subtract( ((RubyInteger) y).getBigIntegerValue() );
if (c.signum() > 0) return RubyFixnum.one(context.runtime); // x > y
if (c.signum() < 0) return RubyFixnum.minus_one(context.runtime); // x < y
return RubyFixnum.zero(context.runtime);
}
return sites(context).op_cmp.call(context, x, x, y);
}