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/