From 900bb7fcf52e046a2d22934383431a4406c9d299 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Thu, 9 Dec 2021 21:35:33 +0900 Subject: [PATCH] Allow passing both float and precision in BigDecimal#div Fix GH-212. --- ext/bigdecimal/bigdecimal.c | 6 +++++- test/bigdecimal/test_bigdecimal.rb | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 47b10d6a..36173f35 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1938,11 +1938,15 @@ BigDecimal_div2(VALUE self, VALUE b, VALUE n) Real *res = NULL; Real *av = NULL, *bv = NULL, *cv = NULL; size_t mx = ix + VpBaseFig()*2; + size_t b_prec = ix; size_t pl = VpSetPrecLimit(0); GUARD_OBJ(cv, VpCreateRbObject(mx + VpBaseFig(), "0", true)); GUARD_OBJ(av, GetVpValue(self, 1)); - GUARD_OBJ(bv, GetVpValue(b, 1)); + if (RB_FLOAT_TYPE_P(b) && b_prec > BIGDECIMAL_DOUBLE_FIGURES) { + b_prec = BIGDECIMAL_DOUBLE_FIGURES; + } + GUARD_OBJ(bv, GetVpValueWithPrec(b, b_prec, 1)); mx = av->Prec + bv->Prec + 2; if (mx <= cv->MaxPrec) mx = cv->MaxPrec + 1; GUARD_OBJ(res, VpCreateRbObject((mx * 2 + 2)*VpBaseFig(), "#0", true)); diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 273abf78..9e8f0d59 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -1091,6 +1091,16 @@ def test_div_bigdecimal end end + def test_div_bigdecimal_with_float_and_precision + x = BigDecimal(5) + y = 5.1 + assert_equal(x.div(BigDecimal(y, 0), 8), + x.div(y, 8)) + + assert_equal(x.div(BigDecimal(y, 0), 100), + x.div(y, 100)) + end + def test_abs_bigdecimal x = BigDecimal((2**100).to_s) assert_equal(1267650600228229401496703205376, x.abs)