Skip to content

Commit

Permalink
Showing 4 changed files with 29 additions and 11 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/bignum/div_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/bignum/divide_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -131,7 +131,14 @@ public abstract static class DivNode extends BignumCoreMethodNode {

@Specialization
public Object div(DynamicObject a, long b) {
return fixnumOrBignum(Layouts.BIGNUM.getValue(a).divide(BigInteger.valueOf(b)));
final BigInteger bBigInt = BigInteger.valueOf(b);
final BigInteger aBigInt = Layouts.BIGNUM.getValue(a);
final BigInteger result = aBigInt.divide(bBigInt);
if (result.signum() == -1 && !aBigInt.mod(bBigInt.abs()).equals(BigInteger.ZERO)) {
return fixnumOrBignum(result.subtract(BigInteger.ONE));
} else {
return fixnumOrBignum(result);
}
}

@Specialization
@@ -141,7 +148,14 @@ public double div(DynamicObject a, double b) {

@Specialization(guards = "isRubyBignum(b)")
public Object div(DynamicObject a, DynamicObject b) {
return fixnumOrBignum(Layouts.BIGNUM.getValue(a).divide(Layouts.BIGNUM.getValue(b)));
final BigInteger aBigInt = Layouts.BIGNUM.getValue(a);
final BigInteger bBigInt = Layouts.BIGNUM.getValue(b);
final BigInteger result = aBigInt.divide(bBigInt);
if (result.signum() == -1 && !aBigInt.mod(bBigInt.abs()).equals(BigInteger.ZERO)) {
return fixnumOrBignum(result.subtract(BigInteger.ONE));
} else {
return fixnumOrBignum(result);
}
}

}
Original file line number Diff line number Diff line change
@@ -350,21 +350,27 @@ public double div(long a, double b) {
return a / b;
}

@Specialization(guards = "isRubyBignum(b)")
@Specialization(guards = {"!isLongMinValue(a)", "isRubyBignum(b)"})
public int div(long a, DynamicObject b) {
if (a == Long.MIN_VALUE) {
// -Long.MIN_VALUE is a BigNum so a special case is needed
return BigInteger.valueOf(a).divide(Layouts.BIGNUM.getValue(b)).intValue();
} else {
return 0;
}
assert Layouts.BIGNUM.getValue(b).compareTo(BigInteger.valueOf(Long.MAX_VALUE)) == 1 ||
Layouts.BIGNUM.getValue(b).compareTo(BigInteger.valueOf(Long.MIN_VALUE)) == -1;
return 0;
}

@Specialization(guards = {"isLongMinValue(a)", "isRubyBignum(b)"})
public int divEdgeCase(long a, DynamicObject b) {
return -(Layouts.BIGNUM.getValue(b).signum());
}

@Specialization(guards = "!isRubyBignum(b)")
public Object divCoerced(VirtualFrame frame, long a, DynamicObject b) {
return ruby("redo_coerced :/, b", "b", b);
}

public static boolean isLongMinValue(long a) {
return a == Long.MIN_VALUE;
}

}

@CoreMethod(names = "%", required = 1)

0 comments on commit abffb3f

Please sign in to comment.