[前][次][番号順一覧][スレッド一覧]

ruby-changes:70993

From: Kenta <ko1@a...>
Date: Mon, 24 Jan 2022 10:57:00 +0900 (JST)
Subject: [ruby-changes:70993] 7db195d521 (master): [ruby/bigdecimal] Fix the maximum precision of the quotient

https://git.ruby-lang.org/ruby.git/commit/?id=7db195d521

From 7db195d521337f78b4477b5730514b78fad8d5a1 Mon Sep 17 00:00:00 2001
From: Kenta Murata <mrkn@m...>
Date: Wed, 19 Jan 2022 15:53:36 +0900
Subject: [ruby/bigdecimal] Fix the maximum precision of the quotient

Fixes https://github.com/ruby/bigdecimal/pull/220

https://github.com/ruby/bigdecimal/commit/127a1b5a31
---
 ext/bigdecimal/bigdecimal.c        | 15 +++++++--------
 test/bigdecimal/test_bigdecimal.rb |  7 +++++++
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index f4dcb2ee7ab..fc74c0be539 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -1647,18 +1647,16 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1647
     SAVE(b);
     *div = b;
 
-    mx = (a->Prec > b->Prec) ? a->Prec : b->Prec;
-    mx *= BASE_FIG;
-
     BigDecimal_count_precision_and_scale(self, &a_prec, NULL);
     BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
     mx = (a_prec > b_prec) ? a_prec : b_prec;
+    mx *= 2;
 
     if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
         mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
 
     GUARD_OBJ((*c), VpCreateRbObject(mx + 2*BASE_FIG, "#0", true));
-    GUARD_OBJ((*res), VpCreateRbObject(mx*2 + 2*BASE_FIG, "#0", true));
+    GUARD_OBJ((*res), VpCreateRbObject((mx + 1)*2 + 2*BASE_FIG, "#0", true));
     VpDivd(*c, *res, a, b);
 
     return Qnil;
@@ -1808,6 +1806,8 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L1806
     BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
 
     mx = (a_prec > b_prec) ? a_prec : b_prec;
+    mx *= 2;
+
     if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
         mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
 
@@ -5931,18 +5931,17 @@ VpDivd(Real *c, Real *r, Real *a, Real *b) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L5931
     word_c = c->MaxPrec;
     word_r = r->MaxPrec;
 
-    ind_c = 0;
-    ind_r = 1;
-
     if (word_a >= word_r) goto space_error;
 
+    ind_r = 1;
     r->frac[0] = 0;
     while (ind_r <= word_a) {
 	r->frac[ind_r] = a->frac[ind_r - 1];
 	++ind_r;
     }
-
     while (ind_r < word_r) r->frac[ind_r++] = 0;
+
+    ind_c = 0;
     while (ind_c < word_c) c->frac[ind_c++] = 0;
 
     /* initial procedure */
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index 11e69282836..0cd85249adc 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -973,6 +973,13 @@ class TestBigDecimal < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L973
     assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 }
   end
 
+  def test_div_gh220
+    x = BigDecimal("1.0")
+    y = BigDecimal("3672577333.6608990499165058135986328125")
+    c = BigDecimal("0.272288343892592687909520102748926752911779209181321744700032723729015151607289998e-9")
+    assert_equal(c, x / y, "[GH-220]")
+  end
+
   def test_div_precision
     bug13754 = '[ruby-core:82107] [Bug #13754]'
     a = BigDecimal('101')
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]