From: "phasis68 (Heesob Park)" <phasis@...> Date: 2013-12-30T16:28:32+09:00 Subject: [ruby-core:59397] [ruby-trunk - Bug #9316] BigDecimal division in Ruby 2.1 Issue #9316 has been updated by phasis68 (Heesob Park). It seems that the size of exponenent affects the precison of division result, but that is a wrong assumption. I think the mininum precison is required regardless of the size of exponent. irb(main):001:0> puts BigDecimal.new('1') / BigDecimal.new('3') 0.333333333E0 irb(main):002:0> puts BigDecimal.new('0.1') / BigDecimal.new('0.3') 0.0 irb(main):003:0> puts BigDecimal.new('0.01') / BigDecimal.new('0.03') 0.0 irb(main):004:0> puts BigDecimal.new('0.001') / BigDecimal.new('0.003') 0.0 irb(main):005:0> puts BigDecimal.new('0.00000000001') / BigDecimal.new('0.00000000003') 0.333333333E0 Here is a simple patch to ensure the minimun precison of division result. diff --git a/bigdecimal.c b/bigdecimal.c.new index e0b7c01..615c15f 100644 --- a/bigdecimal.c +++ b/bigdecimal.c.new @@ -1222,6 +1222,7 @@ BigDecimal_divide(Real **c, Real **res, Real **div, VALUE self, VALUE r) *div = b; mx = a->Prec + vabs(a->exponent); if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); + if (mx<3) mx = 3; mx =(mx + 1) * VpBaseFig(); GUARD_OBJ((*c), VpCreateRbObject(mx, "#0")); GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); @@ -1323,6 +1324,7 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) mx = a->Prec + vabs(a->exponent); if (mx<b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); + if (mx<3) mx = 3; mx = (mx + 1) * VpBaseFig(); GUARD_OBJ(c, VpCreateRbObject(mx, "0")); GUARD_OBJ(res, VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0")); After appling the patch, the results are all equal. irb(main):001:0> puts BigDecimal.new('1') / BigDecimal.new('3') 0.333333333333333333E0 irb(main):002:0> puts BigDecimal.new('0.1') / BigDecimal.new('0.3') 0.333333333333333333E0 irb(main):003:0> puts BigDecimal.new('0.01') / BigDecimal.new('0.03') 0.333333333333333333E0 irb(main):004:0> puts BigDecimal.new('0.001') / BigDecimal.new('0.003') 0.333333333333333333E0 irb(main):005:0> puts BigDecimal.new('0.00000000001') / BigDecimal.new('0.00000000003') 0.333333333333333333E0 ---------------------------------------- Bug #9316: BigDecimal division in Ruby 2.1 https://bugs.ruby-lang.org/issues/9316#change-43961 Author: abernardes (Andre Bernardes) Status: Assigned Priority: Normal Assignee: mrkn (Kenta Murata) Category: lib Target version: current: 2.2.0 ruby -v: ruby 2.1.0p0 (2013-12-25 revision 44422) [x86_64-darwin13.0] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN =begin When updating an app to Ruby 2.1, and I ran into the following difference between ruby 2.0.0-p353 and ruby 2.1.0 when dividing two BigDecimals: ((*Ruby 2.0.0p353:*)) 2.0.0p353 :002 > (BigDecimal.new("1472.0") / BigDecimal.new("0.99")).to_f => 1486.868686869 ((*Ruby 2.1.0p0:*)) 2.1.0p0 :006 > (BigDecimal.new("1472.0") / BigDecimal.new("0.99")).to_f => 1487.0 =end -- http://bugs.ruby-lang.org/