From 1cb92487f79f1976d2526ebf6bbfb83872c45837 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Fri, 15 Jan 2021 10:44:45 +0900 Subject: [PATCH] Fix for the coerce cases in divide and DoDivmod --- ext/bigdecimal/bigdecimal.c | 26 ++++++++++++++++---------- test/bigdecimal/test_bigdecimal.rb | 13 +++++++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index b095ec55..4a30355f 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -1356,16 +1356,19 @@ BigDecimal_divide(VALUE self, VALUE r, Real **c, Real **res, Real **div) TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a); SAVE(a); - VALUE rr = Qnil; - if (RB_TYPE_P(r, T_FLOAT)) { + VALUE rr = r; + if (is_kind_of_BigDecimal(rr)) { + /* do nothing */ + } + else if (RB_INTEGER_TYPE_P(r)) { + rr = rb_inum_convert_to_BigDecimal(r, 0, true); + } + else if (RB_TYPE_P(r, T_FLOAT)) { rr = rb_float_convert_to_BigDecimal(r, 0, true); } else if (RB_TYPE_P(r, T_RATIONAL)) { rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true); } - else { - rr = rb_convert_to_BigDecimal(r, 0, false); - } if (!is_kind_of_BigDecimal(rr)) { return DoSomeOne(self, r, '/'); @@ -1428,16 +1431,19 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a); SAVE(a); - VALUE rr = Qnil; - if (RB_TYPE_P(r, T_FLOAT)) { + VALUE rr = r; + if (is_kind_of_BigDecimal(rr)) { + /* do nothing */ + } + else if (RB_INTEGER_TYPE_P(r)) { + rr = rb_inum_convert_to_BigDecimal(r, 0, true); + } + else if (RB_TYPE_P(r, T_FLOAT)) { rr = rb_float_convert_to_BigDecimal(r, 0, true); } else if (RB_TYPE_P(r, T_RATIONAL)) { rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true); } - else { - rr = rb_convert_to_BigDecimal(r, 0, false); - } if (!is_kind_of_BigDecimal(rr)) { return Qfalse; diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index a343c8a4..14e35bee 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -974,6 +974,15 @@ def test_div_with_rational assert_kind_of(BigDecimal, BigDecimal("3") / 1.quo(3)) end + def test_div_with_complex + q = BigDecimal("3") / 1i + assert_kind_of(Complex, q) + end + + def test_div_error + assert_raise(TypeError) { BigDecimal(20) / '2' } + end + def test_mod x = BigDecimal((2**100).to_s) assert_equal(1, x % 3) @@ -1028,6 +1037,10 @@ def test_divmod_precision assert_equal((a/b), q) end + def test_divmod_error + assert_raise(TypeError) { BigDecimal(20).divmod('2') } + end + def test_add_bigdecimal x = BigDecimal((2**100).to_s) assert_equal(3000000000000000000000000000000, x.add(x, 1))