From 7db195d521337f78b4477b5730514b78fad8d5a1 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Wed, 19 Jan 2022 15:53:36 +0900 Subject: [PATCH] [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 f4dcb2ee7a..fc74c0be53 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) 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) 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) 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 11e6928283..0cd85249ad 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -973,6 +973,13 @@ class TestBigDecimal < Test::Unit::TestCase 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')