[ruby/bigdecimal] Stop using GetVpValueWithPrec in rb_float_convert_to_BigDecimal

33e7c50263
d3c1b0b921
This commit is contained in:
Kenta Murata 2021-01-09 15:10:20 +09:00
parent 89f3125207
commit fb18a8113a
No known key found for this signature in database
GPG key ID: CEFE8AFB6081B062

View file

@ -199,6 +199,7 @@ cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v)
} }
static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); 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* static Real*
GetVpValueWithPrec(VALUE v, long prec, int must) GetVpValueWithPrec(VALUE v, long prec, int must)
@ -208,27 +209,14 @@ GetVpValueWithPrec(VALUE v, long prec, int must)
VALUE num, bg; VALUE num, bg;
char szD[128]; char szD[128];
VALUE orig = Qundef; VALUE orig = Qundef;
double d;
again: again:
switch(TYPE(v)) { switch(TYPE(v)) {
case T_FLOAT: case T_FLOAT: {
if (prec < 0) goto unable_to_coerce_without_prec; VALUE obj = rb_float_convert_to_BigDecimal(v, prec, must);
if (prec > (long)DBLE_FIG) goto SomeOneMayDoIt; TypedData_Get_Struct(obj, Real, &BigDecimal_data_type, pv);
d = RFLOAT_VALUE(v); return pv;
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_RATIONAL: case T_RATIONAL:
if (prec < 0) goto unable_to_coerce_without_prec; 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 static VALUE
rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception)
{ {
double d = RFLOAT_VALUE(val); double d = RFLOAT_VALUE(val);
if (!isfinite(d)) { if (!isfinite(d)) {
Real *vp = VpCreateRbObject(1, NULL, true); /* vp->obj is allocated */ Real *vp = VpCreateRbObject(1, NULL, true); /* vp->obj is allocated */
VpDtoV(vp, d); 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."); 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); return check_exception(vp->obj);
} }