The actual number of significant digits used in computation is usually
larger than the specified number.
static VALUE
BigDecimal_new(int argc, VALUE *argv, VALUE self)
{
ENTER(5);
Real *pv;
size_t mf;
VALUE nFig;
VALUE iniValue;
if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) {
mf = 0;
}
else {
mf = GetPositiveInt(nFig);
}
switch (TYPE(iniValue)) {
case T_DATA:
if (is_kind_of_BigDecimal(iniValue)) {
pv = VpDup(DATA_PTR(iniValue));
return ToValue(pv);
}
break;
case T_FIXNUM:
/* fall through */
case T_BIGNUM:
return ToValue(GetVpValue(iniValue, 1));
case T_FLOAT:
if (mf > DBL_DIG+1) {
rb_raise(rb_eArgError, "precision too large.");
}
/* fall through */
case T_RATIONAL:
if (NIL_P(nFig)) {
rb_raise(rb_eArgError, "can't omit precision for a Rational.");
}
return ToValue(GetVpValueWithPrec(iniValue, mf, 1));
case T_STRING:
/* fall through */
default:
break;
}
SafeStringValue(iniValue);
GUARD_OBJ(pv, VpNewRbClass(mf, RSTRING_PTR(iniValue),self));
return ToValue(pv);
}