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: 4a340535b222
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: cce752cc2dd8
Choose a head ref
  • 14 commits
  • 12 files changed
  • 1 contributor

Commits on Jan 19, 2018

  1. introduce a 'fast' isZero for Numerics + also override pos/neg checks

    + cleanup RubyRational's internals - confusing IRubyObject clazz param
    kares committed Jan 19, 2018

    Verified

    This commit was signed with the committer’s verified signature.
    targos Michaël Zasso
    Copy the full SHA
    641aac0 View commit details
  2. Copy the full SHA
    2e9095a View commit details
  3. Verified

    This commit was signed with the committer’s verified signature.
    tpoisseau tpoisseau
    Copy the full SHA
    c903f31 View commit details
  4. Copy the full SHA
    20fa61f View commit details
  5. Copy the full SHA
    b78d7de View commit details
  6. Copy the full SHA
    0aeb492 View commit details
  7. Copy the full SHA
    ac815f8 View commit details
  8. Copy the full SHA
    15327dd View commit details
  9. Copy the full SHA
    36ff6cf View commit details
  10. Copy the full SHA
    dd958e8 View commit details
  11. Copy the full SHA
    5d61b99 View commit details
  12. Copy the full SHA
    61a117a View commit details
  13. Copy the full SHA
    d51c7d2 View commit details
  14. Copy the full SHA
    cce752c View commit details
19 changes: 14 additions & 5 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
@@ -96,20 +96,24 @@ public static RubyBignum newBignum(Ruby runtime, long value) {
*/
public static RubyBignum newBignum(Ruby runtime, double value) {
try {
return newBignum(runtime, new BigDecimal(value).toBigInteger());
return newBignum(runtime, toBigInteger(value));
} catch (NumberFormatException nfe) {
throw runtime.newFloatDomainError(Double.toString(value));
}
}

public static BigInteger toBigInteger(double value) {
return new BigDecimal(value).toBigInteger();
}

/**
* Return a Bignum or Fixnum (Integer) for the given value, or raise FloatDomainError if it is out of range.
*
* MRI: rb_dbl2big
*/
public static RubyInteger newBignorm(Ruby runtime, double value) {
try {
return bignorm(runtime, new BigDecimal(value).toBigInteger());
return bignorm(runtime, toBigInteger(value));
} catch (NumberFormatException nfe) {
throw runtime.newFloatDomainError(Double.toString(value));
}
@@ -160,7 +164,7 @@ public BigInteger getValue() {

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

/* ================
@@ -418,7 +422,7 @@ public IRubyObject coerce(IRubyObject other) {
*/
@Override
public IRubyObject op_uminus(ThreadContext context) {
return bignorm(getRuntime(), value.negate());
return bignorm(context.runtime, value.negate());
}

/** rb_big_plus
@@ -1028,7 +1032,12 @@ public IRubyObject size(ThreadContext context) {

@Override
public IRubyObject zero_p(ThreadContext context) {
return context.runtime.newBoolean(value.equals(BigInteger.ZERO));
return context.runtime.newBoolean(isZero());
}

@Override
public final boolean isZero() {
return value.equals(BigInteger.ZERO);
}

public static void marshalTo(RubyBignum bignum, MarshalStream output) throws IOException {
18 changes: 14 additions & 4 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
@@ -186,7 +186,7 @@ public BigInteger getBigIntegerValue() {

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

public static RubyFixnum newFixnum(Ruby runtime, long value) {
@@ -450,10 +450,14 @@ public IRubyObject to_sym() {
*/
@Override
public IRubyObject op_uminus(ThreadContext context) {
return negate(context.runtime, value);
}

private static RubyInteger negate(final Ruby runtime, final long value) {
if (value == MIN) { // a gotcha
return RubyBignum.newBignum(getRuntime(), BigInteger.valueOf(value).negate());
return RubyBignum.newBignum(runtime, BigInteger.valueOf(value).negate());
}
return RubyFixnum.newFixnum(getRuntime(), -value);
return RubyFixnum.newFixnum(runtime, -value);
}

/** fix_plus
@@ -1258,6 +1262,7 @@ public IRubyObject size(ThreadContext context) {
return newFixnum((long) ((BIT_SIZE + 7) / 8));
}

@Deprecated
public IRubyObject zero_p() {
return zero_p(getRuntime().getCurrentContext());
}
@@ -1267,7 +1272,12 @@ public IRubyObject zero_p() {
*/
@Override
public IRubyObject zero_p(ThreadContext context) {
return RubyBoolean.newBoolean(getRuntime(), value == 0);
return RubyBoolean.newBoolean(context.runtime, value == 0);
}

@Override
public final boolean isZero() {
return value == 0;
}

@Override
57 changes: 37 additions & 20 deletions core/src/main/java/org/jruby/RubyFloat.java
Original file line number Diff line number Diff line change
@@ -175,18 +175,36 @@ public int getIntValue() {

@Override
public BigInteger getBigIntegerValue() {
return BigInteger.valueOf((long)value);
return RubyBignum.toBigInteger(value);
}

@Override
public RubyFloat convertToFloat() {
return this;
}

@Override
public RubyInteger convertToInteger() {
if (RubyFixnum.MIN <= value && value <= RubyFixnum.MAX) {
return RubyFixnum.newFixnum(getRuntime(), (long) value);
}
return RubyBignum.newBignum(getRuntime(), getBigIntegerValue());
}

public int signum() {
return (int) Math.signum(value); // NOTE: (int) NaN ?
}

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

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

public static RubyFloat newFloat(Ruby runtime, double value) {
return new RubyFloat(runtime, value);
}
@@ -677,6 +695,11 @@ public IRubyObject zero_p(ThreadContext context) {
return RubyBoolean.newBoolean(context.runtime, value == 0.0);
}

@Override
public final boolean isZero() {
return value == 0.0;
}

/**
* MRI: flo_truncate
*/
@@ -722,7 +745,7 @@ public IRubyObject denominator(ThreadContext context) {
*
*/
static final int DBL_MANT_DIG = 53;
static final int FLT_RADIX = 2;

@JRubyMethod(name = "to_r")
public IRubyObject to_r(ThreadContext context) {
long[] exp = new long[1];
@@ -732,9 +755,9 @@ public IRubyObject to_r(ThreadContext context) {

Ruby runtime = context.runtime;

IRubyObject rf = RubyNumeric.dbl2ival(runtime, f);
IRubyObject rn = RubyFixnum.newFixnum(runtime, n);
return f_mul(context, rf, f_expt(context, RubyFixnum.newFixnum(runtime, FLT_RADIX), rn));
RubyInteger rf = RubyNumeric.dbl2ival(runtime, f);
RubyFixnum rn = RubyFixnum.newFixnum(runtime, n);
return f_mul(context, rf, f_expt(context, RubyFixnum.two(runtime), rn));
}

/** float_rationalize
@@ -747,16 +770,13 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
}

final Ruby runtime = context.runtime;
RubyFixnum one = RubyFixnum.one(runtime);

IRubyObject eps, a, b;
if (args.length != 0) {
eps = f_abs(context, args[0]);
a = f_sub(context, this, eps);
b = f_add(context, this, eps);
} else {
IRubyObject flt;
IRubyObject p, q;
long[] exp = new long[1];

// float_decode_internal
@@ -767,26 +787,23 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
RubyInteger rf = RubyBignum.newBignorm(runtime, f);
RubyFixnum rn = RubyFixnum.newFixnum(runtime, n);

if (rf.zero_p(context).isTrue() || fix2int(rn) >= 0) {
if (rf.isZero() || fix2int(rn) >= 0) {
return RubyRational.newRationalRaw(runtime, rf.op_lshift(context, rn));
}

RubyInteger two_times_f, den;

RubyFixnum two = RubyFixnum.two(runtime);
two_times_f = (RubyInteger) two.op_mul(context, rf);
den = (RubyInteger) RubyFixnum.one(runtime).op_lshift(context, RubyFixnum.one(runtime).op_minus(context, n));
final RubyFixnum one = RubyFixnum.one(runtime);
RubyInteger den;

a = RubyRational.newRationalRaw(runtime, two_times_f.op_minus(context, RubyFixnum.one(runtime)), den);
b = RubyRational.newRationalRaw(runtime, two_times_f.op_plus(context, RubyFixnum.one(runtime)), den);
RubyInteger two_times_f = (RubyInteger) rf.op_mul(context, 2);
den = (RubyInteger) one.op_lshift(context, RubyFixnum.one(runtime).op_minus(context, n));

a = RubyRational.newRationalRaw(runtime, two_times_f.op_minus(context, 1), den);
b = RubyRational.newRationalRaw(runtime, two_times_f.op_plus(context, 1), den);
}

if (sites(context).op_equal.call(context, a, a, b).isTrue()) return f_to_r(context, this);

IRubyObject[] ary = new IRubyObject[2];
ary[0] = a;
ary[1] = b;
IRubyObject[] ans = nurat_rationalize_internal(context, ary);
IRubyObject[] ans = nurat_rationalize_internal(context, a, b);

return RubyRational.newRationalRaw(runtime, ans[0], ans[1]);
}
26 changes: 18 additions & 8 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
@@ -122,6 +122,16 @@ public IRubyObject isPositive(ThreadContext context) {
return context.runtime.newBoolean(signum() > 0);
}

// @Override // NOTE: could be public + defined on Numeric
final boolean isNegative() {
return signum() < 0;
}

// @Override // NOTE: could be public + defined on Numeric
final boolean isPositive() {
return signum() > 0;
}

/* ================
* Instance Methods
* ================
@@ -489,7 +499,7 @@ protected IRubyObject roundShared(ThreadContext context, int ndigits, RoundingMo
n = (RubyNumeric) this.op_minus(context, r);
r = (RubyNumeric) r.op_cmp(context, h);
if (r.isPositive(context).isTrue() ||
(r.zero_p(context).isTrue() && doRoundCheck(context, roundingMode, this, n, f))) {
(r.isZero() && doRoundCheck(context, roundingMode, this, n, f))) {
n = (RubyNumeric) n.op_plus(context, f);
}
return n;
@@ -630,25 +640,25 @@ public IRubyObject lcm(ThreadContext context, IRubyObject other) {
*/
@JRubyMethod(name = "gcdlcm")
public IRubyObject gcdlcm(ThreadContext context, IRubyObject other) {
other = RubyInteger.intValue(context, other);
return context.runtime.newArray(f_gcd(context, this, other), f_lcm(context, this, other));
final RubyInteger otherInt = RubyInteger.intValue(context, other);
return context.runtime.newArray(f_gcd(context, this, otherInt), f_lcm(context, this, otherInt));
}

static IRubyObject intValue(ThreadContext context, IRubyObject num) {
IRubyObject i;
static RubyInteger intValue(ThreadContext context, IRubyObject num) {
RubyInteger i;
if (( i = RubyInteger.toInteger(context, num) ) == null) {
throw context.runtime.newTypeError("not an integer");
}
return i;
}

static IRubyObject toInteger(ThreadContext context, IRubyObject num) {
if (num instanceof RubyInteger) return num;
static RubyInteger toInteger(ThreadContext context, IRubyObject num) {
if (num instanceof RubyInteger) return (RubyInteger) num;
if (num instanceof RubyNumeric && !integer_p(context).call(context, num, num).isTrue()) { // num.integer?
return null;
}
if (num instanceof RubyString) return null; // do not want String#to_i
return num.checkCallMethod(context, sites(context).to_i_checked);
return (RubyInteger) num.checkCallMethod(context, sites(context).to_i_checked);
}

@JRubyMethod(name = "digits")
7 changes: 5 additions & 2 deletions core/src/main/java/org/jruby/RubyNumeric.java
Original file line number Diff line number Diff line change
@@ -744,8 +744,7 @@ public final IRubyObject quo_19(ThreadContext context, IRubyObject other) {
@JRubyMethod(name = "div")
public IRubyObject div(ThreadContext context, IRubyObject other) {
if (other instanceof RubyNumeric) {
RubyNumeric numeric = (RubyNumeric) other;
if (numeric.zero_p(context).isTrue()) {
if (((RubyNumeric) other).isZero()) {
throw context.runtime.newZeroDivisionError();
}
}
@@ -859,6 +858,10 @@ public IRubyObject zero_p(ThreadContext context) {
return equalInternal(context, this, RubyFixnum.zero(runtime)) ? runtime.getTrue() : runtime.getFalse();
}

public boolean isZero() {
return zero_p(getRuntime().getCurrentContext()).isTrue();
}

/** num_nonzero_p
*
*/
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyRandom.java
Original file line number Diff line number Diff line change
@@ -302,7 +302,7 @@ static IRubyObject randKernel(ThreadContext context, IRubyObject[] args) {
}

RubyInteger max = arg.convertToInteger();
if (max.zero_p(context).isTrue()) {
if (max.isZero()) {
return randFloat(context, random);
}
IRubyObject r = randInt(context, random, max, false);
Loading