Skip to content

Commit

Permalink
`op_mod' overload with long argument + refactor checkShift internal
Browse files Browse the repository at this point in the history
  • Loading branch information
kares committed Feb 15, 2018
1 parent ea6131a commit 0101188
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 26 deletions.
57 changes: 31 additions & 26 deletions core/src/main/java/org/jruby/RubyBignum.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,12 @@ public static double big2dbl(RubyBignum value) {
return dbl;
}

private IRubyObject checkShiftDown(RubyBignum other) {
if (other.value.signum() == 0) return RubyFixnum.zero(getRuntime());
private RubyFixnum checkShiftDown(ThreadContext context, RubyBignum other) {
if (other.value.signum() == 0) return RubyFixnum.zero(context.runtime);
if (value.compareTo(LONG_MIN) < 0 || value.compareTo(LONG_MAX) > 0) {
return other.value.signum() >= 0 ? RubyFixnum.zero(getRuntime()) : RubyFixnum.minus_one(getRuntime());
return other.value.signum() >= 0 ? RubyFixnum.zero(context.runtime) : RubyFixnum.minus_one(context.runtime);
}
return getRuntime().getNil();
return null;
}

/**
Expand Down Expand Up @@ -630,27 +630,32 @@ public IRubyObject divmod(ThreadContext context, IRubyObject other) {
*/
@JRubyMethod(name = {"%", "modulo"}, required = 1)
public IRubyObject op_mod(ThreadContext context, IRubyObject other) {
if (!other.isNil() && other instanceof RubyFloat
&& ((RubyFloat)other).getDoubleValue() == 0) {
throw context.runtime.newZeroDivisionError();
if (other instanceof RubyFixnum) {
return op_mod(context, ((RubyFixnum) other).getLongValue());
}

final BigInteger otherValue;
if (other instanceof RubyFixnum) {
otherValue = fix2big((RubyFixnum) other);
} else if (other instanceof RubyBignum) {
if (other instanceof RubyBignum) {
otherValue = ((RubyBignum) other).value;
} else {
if (other instanceof RubyFloat && ((RubyFloat) other).getDoubleValue() == 0) {
throw context.runtime.newZeroDivisionError();
}
return coerceBin(context, sites(context).op_mod, other);
if (otherValue.signum() == 0) throw context.runtime.newZeroDivisionError();

BigInteger result = value.mod(otherValue.abs());
if (otherValue.signum() == -1 && result.signum() != 0) result = otherValue.add(result);
return bignorm(context.runtime, result);
}

if (otherValue.signum() == 0) throw context.runtime.newZeroDivisionError();
if (other instanceof RubyFloat && ((RubyFloat) other).getDoubleValue() == 0) {
throw context.runtime.newZeroDivisionError();
}
return coerceBin(context, sites(context).op_mod, other);
}

@Override
public IRubyObject op_mod(ThreadContext context, long other) {
if (other == 0) throw context.runtime.newZeroDivisionError();

BigInteger result = value.mod(otherValue.abs());
if (otherValue.signum() == -1 && result.signum() != 0) result = otherValue.add(result);
BigInteger result = value.mod(long2big(other < 0 ? -other : other));
if (other < 0 && result.signum() != 0) result = long2big(other).add(result);
return bignorm(context.runtime, result);
}

Expand Down Expand Up @@ -854,13 +859,13 @@ public IRubyObject op_lshift(ThreadContext context, IRubyObject other) {

for (;;) {
if (other instanceof RubyFixnum) {
shift = ((RubyFixnum)other).getLongValue();
shift = ((RubyFixnum) other).getLongValue();
break;
} else if (other instanceof RubyBignum) {
RubyBignum otherBignum = (RubyBignum)other;
RubyBignum otherBignum = (RubyBignum) other;
if (otherBignum.value.signum() < 0) {
IRubyObject tmp = otherBignum.checkShiftDown(this);
if (!tmp.isNil()) return tmp;
IRubyObject tmp = otherBignum.checkShiftDown(context, this);
if (tmp != null) return tmp;
}
shift = big2long(otherBignum);
break;
Expand All @@ -880,13 +885,13 @@ public IRubyObject op_rshift(ThreadContext context, IRubyObject other) {

for (;;) {
if (other instanceof RubyFixnum) {
shift = ((RubyFixnum)other).getLongValue();
shift = ((RubyFixnum) other).getLongValue();
break;
} else if (other instanceof RubyBignum) {
RubyBignum otherBignum = (RubyBignum)other;
RubyBignum otherBignum = (RubyBignum) other;
if (otherBignum.value.signum() >= 0) {
IRubyObject tmp = otherBignum.checkShiftDown(this);
if (!tmp.isNil()) return tmp;
IRubyObject tmp = otherBignum.checkShiftDown(context, this);
if (tmp != null) return tmp;
}
shift = big2long(otherBignum);
break;
Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/org/jruby/RubyFixnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ public IRubyObject op_mod(ThreadContext context, IRubyObject other) {
return coerceBin(context, sites(context).op_mod, other);
}

@Override
public IRubyObject op_mod(ThreadContext context, long other) {
return moduloFixnum(context, other);
}
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,10 @@ public final IRubyObject div_div(ThreadContext context, IRubyObject other) {
@JRubyMethod(name = {"%", "modulo"})
public abstract IRubyObject op_mod(ThreadContext context, IRubyObject other);

public IRubyObject op_mod(ThreadContext context, long other) {
return op_mod(context, RubyFixnum.newFixnum(context.runtime, other));
}

@JRubyMethod(name = "**")
public abstract IRubyObject op_pow(ThreadContext context, IRubyObject other);

Expand Down

0 comments on commit 0101188

Please sign in to comment.