diff options
-rw-r--r-- | ext/bigdecimal/bigdecimal.c | 13 | ||||
-rw-r--r-- | test/bigdecimal/test_bigdecimal.rb | 17 |
2 files changed, 21 insertions, 9 deletions
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 7cec33b7c9..71499a7a19 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1508,13 +1508,12 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div) SAVE(b); *div = b; - mx = a->Prec + vabs(a->exponent); - if (mx < b->Prec + vabs(b->exponent)) mx = b->Prec + vabs(b->exponent); - mx++; /* NOTE: An additional digit is needed for the compatibility to - the version 1.2.1 and the former. */ - mx = (mx + 1) * VpBaseFig(); - GUARD_OBJ((*c), VpCreateRbObject(mx, "#0", true)); - GUARD_OBJ((*res), VpCreateRbObject((mx+1) * 2 +(VpBaseFig() + 1), "#0", true)); + mx = (a->Prec > b->Prec) ? a->Prec : b->Prec; + mx *= BASE_FIG; + 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)); VpDivd(*c, *res, a, b); return Qnil; } diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 1e6c59535f..66b58aa124 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -953,9 +953,13 @@ class TestBigDecimal < Test::Unit::TestCase assert_equal(2, BigDecimal("2") / 1) assert_equal(-2, BigDecimal("2") / -1) - assert_equal(BigDecimal('1486.868686869'), BigDecimal('1472.0') / BigDecimal('0.99'), '[ruby-core:59365] [#9316]') + assert_equal(BigDecimal('1486.868686869'), + (BigDecimal('1472.0') / BigDecimal('0.99')).round(9), + '[ruby-core:59365] [#9316]') - assert_equal(4.124045235, BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0')), '[#9305]') + assert_in_delta(4.124045235, + (BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0'))).round(9, half: :up), + 10**Float::MIN_10_EXP, '[#9305]') BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) assert_positive_zero(BigDecimal("1.0") / BigDecimal("Infinity")) @@ -969,6 +973,15 @@ class TestBigDecimal < Test::Unit::TestCase assert_raise_with_message(FloatDomainError, "Computation results in '-Infinity'") { BigDecimal("-1") / 0 } end + def test_dev_precision + bug13754 = '[ruby-core:82107] [Bug #13754]' + a = BigDecimal('101') + b = BigDecimal('0.9163472602589686') + c = a/b + assert(c.precision > b.precision, + "(101/0.9163472602589686).precision >= (0.9163472602589686).precision #{bug13754}") + end + def test_div_with_float assert_kind_of(BigDecimal, BigDecimal("3") / 1.5) assert_equal(BigDecimal("0.5"), BigDecimal(1) / 2.0) |