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: 3b6f3085d9d1
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 850a14b35dc9
Choose a head ref
  • 3 commits
  • 2 files changed
  • 2 contributors

Commits on Oct 27, 2017

  1. Copy the full SHA
    1d47d52 View commit details

Commits on Oct 30, 2017

  1. Use instanceof

    MrBerg committed Oct 30, 2017
    Copy the full SHA
    eba3bf5 View commit details
  2. Merge pull request #4830 from MrBerg/enforce-bigdecimal-limit

    Make BigDecimal::limit work for subtraction and division. Fix issue #1615
    headius authored Oct 30, 2017
    Copy the full SHA
    850a14b View commit details
Showing with 29 additions and 14 deletions.
  1. +13 −13 core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
  2. +16 −1 spec/ruby/library/bigdecimal/limit_spec.rb
26 changes: 13 additions & 13 deletions core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
Original file line number Diff line number Diff line change
@@ -46,12 +46,10 @@
import org.jruby.RubyInteger;
import org.jruby.RubyModule;
import org.jruby.RubyNumeric;
import static org.jruby.RubyNumeric.num2int;
import org.jruby.RubyObject;
import org.jruby.RubyRational;
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyConstant;
import org.jruby.anno.JRubyMethod;
import org.jruby.ast.util.ArgsUtil;
@@ -62,7 +60,6 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import static org.jruby.runtime.builtin.IRubyObject.NULL_ARRAY;
import org.jruby.util.Numeric;
import org.jruby.util.SafeDoubleParser;
import org.jruby.util.StringSupport;
@@ -663,7 +660,7 @@ private RubyBigDecimal setResult() {

private RubyBigDecimal setResult(int scale) {
int prec = RubyFixnum.fix2int(getRuntime().getClass("BigDecimal").searchInternalModuleVariable("vpPrecLimit"));
int prec2 = Math.max(scale, prec);
int prec2 = (scale == 0) ? prec : scale;
if (prec2 > 0 && this.value.scale() > (prec2-getExponent())) {
this.value = this.value.setScale(prec2-getExponent(), BigDecimal.ROUND_HALF_UP);
}
@@ -971,7 +968,7 @@ public IRubyObject op_uminus(ThreadContext context) {

@JRubyMethod(name = "-", required = 1)
public IRubyObject op_minus(ThreadContext context, IRubyObject b) {
return subInternal(context, getVpValue19(context, b, true), b);
return subInternal(context, getVpValue19(context, b, true), b, RubyInteger.int2fix(getRuntime(),0));
}

@Deprecated
@@ -981,21 +978,19 @@ public IRubyObject op_minus19(ThreadContext context, IRubyObject b) {

@JRubyMethod(name = "sub", required = 2)
public IRubyObject sub2(ThreadContext context, IRubyObject b, IRubyObject n) {
// FIXME: Missing handling of n
return subInternal(context, getVpValue19(context, b, false), b);
return subInternal(context, getVpValue19(context, b, false), b, n);
}

@Deprecated
public IRubyObject sub219(ThreadContext context, IRubyObject b, IRubyObject n) {
return sub2(context, b, n);
}

private IRubyObject subInternal(ThreadContext context, RubyBigDecimal val, IRubyObject b) {
private IRubyObject subInternal(ThreadContext context, RubyBigDecimal val, IRubyObject b, IRubyObject n) {
if (val == null) return callCoerced(context, sites(context).op_minus, b);

int prec = getPositiveInt(context, n);
RubyBigDecimal res = handleMinusSpecialValues(context, val);

return res != null ? res : new RubyBigDecimal(context.runtime, value.subtract(val.value)).setResult();
return res != null ? res : new RubyBigDecimal(context.runtime, value.subtract(val.value)).setResult(prec);
}

private RubyBigDecimal handleMinusSpecialValues(ThreadContext context, RubyBigDecimal val) {
@@ -1040,7 +1035,9 @@ public IRubyObject op_quo(ThreadContext context, IRubyObject other) {
int pow = len / 4;
int precision = (pow + 1) * 4 * 2;

return divWithScale(context, val, precision);
IRubyObject result = divWithScale(context, val, precision);
if (result instanceof RubyBigDecimal) return ((RubyBigDecimal) result).setResult();
return result;
}

@Deprecated
@@ -1085,7 +1082,10 @@ public IRubyObject op_div(ThreadContext context, IRubyObject other, IRubyObject
if (isNaN() || val.isNaN()) {
throw context.runtime.newFloatDomainError("Computation results to 'NaN'");
}
return divWithScale(context, val, RubyNumeric.fix2int(digits));
int prec = RubyNumeric.fix2int(digits);
IRubyObject result = divWithScale(context, val, prec);
if (result instanceof RubyBigDecimal) return ((RubyBigDecimal) result).setResult(prec);
return result;
}

private IRubyObject divWithScale(ThreadContext context, RubyBigDecimal val, int scale) {
17 changes: 16 additions & 1 deletion spec/ruby/library/bigdecimal/limit_spec.rb
Original file line number Diff line number Diff line change
@@ -11,20 +11,35 @@
BigDecimal.limit(old)
end

it "use the global limit if no precision is specified" do
it "uses the global limit if no precision is specified" do
BigDecimalSpecs.with_limit(0) do
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.888')
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.888')
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('2.664')
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.296')
end

BigDecimalSpecs.with_limit(1) do
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.9')
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.9')
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('3')
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.3')
end

BigDecimalSpecs.with_limit(2) do
(BigDecimal('0.888') + BigDecimal('0')).should == BigDecimal('0.89')
(BigDecimal('0.888') - BigDecimal('0')).should == BigDecimal('0.89')
(BigDecimal('0.888') * BigDecimal('3')).should == BigDecimal('2.7')
(BigDecimal('0.888') / BigDecimal('3')).should == BigDecimal('0.30')
end
end

it "picks the specified precision over global limit" do
BigDecimalSpecs.with_limit(3) do
BigDecimal('0.888').add(BigDecimal('0'), 2).should == BigDecimal('0.89')
BigDecimal('0.888').sub(BigDecimal('0'), 2).should == BigDecimal('0.89')
BigDecimal('0.888').mult(BigDecimal('3'), 2).should == BigDecimal('2.7')
BigDecimal('0.888').div(BigDecimal('3'), 2).should == BigDecimal('0.30')
end
end
end