[ruby/bigdecimal] Fix the maximum precision of the quotient
Fixes https://github.com/ruby/bigdecimal/pull/220 https://github.com/ruby/bigdecimal/commit/127a1b5a31
This commit is contained in:
parent
506728d0b8
commit
7db195d521
@ -1647,18 +1647,16 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div)
|
|||||||
SAVE(b);
|
SAVE(b);
|
||||||
*div = 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(self, &a_prec, NULL);
|
||||||
BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
|
BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
|
||||||
mx = (a_prec > b_prec) ? a_prec : b_prec;
|
mx = (a_prec > b_prec) ? a_prec : b_prec;
|
||||||
|
mx *= 2;
|
||||||
|
|
||||||
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
|
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
|
||||||
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
|
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
|
||||||
|
|
||||||
GUARD_OBJ((*c), VpCreateRbObject(mx + 2*BASE_FIG, "#0", true));
|
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);
|
VpDivd(*c, *res, a, b);
|
||||||
|
|
||||||
return Qnil;
|
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);
|
BigDecimal_count_precision_and_scale(rr, &b_prec, NULL);
|
||||||
|
|
||||||
mx = (a_prec > b_prec) ? a_prec : b_prec;
|
mx = (a_prec > b_prec) ? a_prec : b_prec;
|
||||||
|
mx *= 2;
|
||||||
|
|
||||||
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
|
if (2*BIGDECIMAL_DOUBLE_FIGURES > mx)
|
||||||
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
|
mx = 2*BIGDECIMAL_DOUBLE_FIGURES;
|
||||||
|
|
||||||
@ -5931,18 +5931,17 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
|
|||||||
word_c = c->MaxPrec;
|
word_c = c->MaxPrec;
|
||||||
word_r = r->MaxPrec;
|
word_r = r->MaxPrec;
|
||||||
|
|
||||||
ind_c = 0;
|
|
||||||
ind_r = 1;
|
|
||||||
|
|
||||||
if (word_a >= word_r) goto space_error;
|
if (word_a >= word_r) goto space_error;
|
||||||
|
|
||||||
|
ind_r = 1;
|
||||||
r->frac[0] = 0;
|
r->frac[0] = 0;
|
||||||
while (ind_r <= word_a) {
|
while (ind_r <= word_a) {
|
||||||
r->frac[ind_r] = a->frac[ind_r - 1];
|
r->frac[ind_r] = a->frac[ind_r - 1];
|
||||||
++ind_r;
|
++ind_r;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ind_r < word_r) r->frac[ind_r++] = 0;
|
while (ind_r < word_r) r->frac[ind_r++] = 0;
|
||||||
|
|
||||||
|
ind_c = 0;
|
||||||
while (ind_c < word_c) c->frac[ind_c++] = 0;
|
while (ind_c < word_c) c->frac[ind_c++] = 0;
|
||||||
|
|
||||||
/* initial procedure */
|
/* initial procedure */
|
||||||
|
@ -973,6 +973,13 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||||||
assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 }
|
assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 }
|
||||||
end
|
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
|
def test_div_precision
|
||||||
bug13754 = '[ruby-core:82107] [Bug #13754]'
|
bug13754 = '[ruby-core:82107] [Bug #13754]'
|
||||||
a = BigDecimal('101')
|
a = BigDecimal('101')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user