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

Commits on Jan 29, 2015

  1. Copy the full SHA
    8fec7f4 View commit details

Commits on Jan 30, 2015

  1. Merge pull request #2537 from k77ch7/fix_GH-2524_on_master

    Fix for issue 2524 on master: [BigDecimal] Loss of precision with different execution order
    enebo committed Jan 30, 2015
    Copy the full SHA
    166445d View commit details
17 changes: 11 additions & 6 deletions core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
Original file line number Diff line number Diff line change
@@ -869,10 +869,16 @@ public IRubyObject op_quo20(ThreadContext context, IRubyObject other) {
}

private IRubyObject op_quo19_20(ThreadContext context, IRubyObject other) {
RubyObject preciseOther = getVpValue19(context, other, true);
RubyBigDecimal preciseOther = getVpValue19(context, other, true);
// regular division with some default precision
// TODO: proper algorithm to set the precision
return op_div(context, preciseOther, getRuntime().newFixnum(200));
// proper algorithm to set the precision
// the precision is multiple of 4
// and the precision is larger than len * 2
int len = value.precision() + preciseOther.value.precision();
int pow = len / 4;
int precision = (pow + 1) * 4 * 2;

return op_div(context, preciseOther, getRuntime().newFixnum(precision));
}

public IRubyObject op_div(ThreadContext context, IRubyObject other) {
@@ -923,10 +929,9 @@ public IRubyObject op_div(ThreadContext context, IRubyObject other, IRubyObject
// MRI behavior: "If digits is 0, the result is the same as the / operator."
if (scale == 0) return op_quo(context, other);

// TODO: better algorithm to set precision needed
int prec = Math.max(200, scale);
MathContext mathContext = new MathContext(scale, getRoundingMode(context.runtime));
return new RubyBigDecimal(context.runtime,
value.divide(val.value, new MathContext(prec, RoundingMode.HALF_UP))).setResult(scale);
value.divide(val.value, mathContext)).setResult(scale);
}

@JRubyMethod(name = "div")
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require 'bigdecimal'

# https://github.com/jruby/jruby/issues/2524
describe 'BigDecimal precision test with different execution order' do
it 'returns same precision ' do
fraction = BigDecimal.new("0.0095") / 365 * BigDecimal.new(50_000)
r1 = fraction * BigDecimal.new(50_000) / BigDecimal.new(100_000)
r2 = fraction * (BigDecimal.new(50_000) / BigDecimal.new(100_000))
expect(r1).to eq(r2)
end
end