From fb18a8113a549185938e3cf12b3494547d077558 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Sat, 9 Jan 2021 15:10:20 +0900 Subject: [ruby/bigdecimal] Stop using GetVpValueWithPrec in rb_float_convert_to_BigDecimal https://github.com/ruby/bigdecimal/commit/33e7c50263 https://github.com/ruby/bigdecimal/commit/d3c1b0b921 --- ext/bigdecimal/bigdecimal.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'ext') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 72c7b34806..5194615475 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -199,6 +199,7 @@ cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) } static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); +static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); static Real* GetVpValueWithPrec(VALUE v, long prec, int must) @@ -208,27 +209,14 @@ GetVpValueWithPrec(VALUE v, long prec, int must) VALUE num, bg; char szD[128]; VALUE orig = Qundef; - double d; again: switch(TYPE(v)) { - case T_FLOAT: - if (prec < 0) goto unable_to_coerce_without_prec; - if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt; - d = RFLOAT_VALUE(v); - if (!isfinite(d)) { - pv = VpCreateRbObject(1, NULL, true); - VpDtoV(pv, d); - return pv; - } - if (d != 0.0) { - v = rb_funcall(v, id_to_r, 0); - goto again; - } - if (1/d < 0.0) { - return VpCreateRbObject(prec, "-0", true); - } - return VpCreateRbObject(prec, "0", true); + case T_FLOAT: { + VALUE obj = rb_float_convert_to_BigDecimal(v, prec, must); + TypedData_Get_Struct(obj, Real, &BigDecimal_data_type, pv); + return pv; + } case T_RATIONAL: if (prec < 0) goto unable_to_coerce_without_prec; @@ -2806,10 +2794,13 @@ rb_inum_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_e } } +static VALUE rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); + static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) { double d = RFLOAT_VALUE(val); + if (!isfinite(d)) { Real *vp = VpCreateRbObject(1, NULL, true); /* vp->obj is allocated */ VpDtoV(vp, d); @@ -2829,7 +2820,18 @@ rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) rb_raise(rb_eArgError, "precision too large."); } - Real *vp = GetVpValueWithPrec(val, digs, 1); + if (d != 0.0) { + val = rb_funcall(val, id_to_r, 0); + return rb_rational_convert_to_BigDecimal(val, digs, raise_exception); + } + + Real *vp; + if (1/d < 0.0) { + vp = VpCreateRbObject(digs, "-0", true); + } + else { + vp = VpCreateRbObject(digs, "0", true); + } return check_exception(vp->obj); } -- cgit v1.2.3