In Files

  • bigdecimal/bigdecimal.c

Methods

Class/Module Index [+]

Quicksearch

Kernel

Public Instance Methods

BigDecimal(arg, exception: true) click to toggle source
BigDecimal(arg, digits, exception: true)

Returns arg converted to a BigDecimal. Numeric types are converted directly. Other types except for String are first converted to String by to_str. Strings can be converted when it has appropriate forms of decimal numbers. Exceptions can be suppressed by passing exception: false.

When arg is a Float and digits is 0, the number of digits is determined by the algorithm of dtoa function written by David M. Gay. That algorithm is based on “How to Print Floating- Point Numbers Accurately” by Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].

arg

The value converted to a BigDecimal.

If it is a String, spaces are ignored and unrecognized characters terminate the value.

digits

The number of significant digits, as an Integer. If omitted, the number of significant digits is determined from arg.

The actual number of significant digits used in computation is usually larger than the specified number.

exception

Whether an exception should be raised on invalid arguments. true by default, if passed false, just returns nil for invalid.

Exceptions

TypeError

If the initial type is neither Integer, Float, Rational, nor BigDecimal, this exception is raised.

TypeError

If the digits is not an Integer, this exception is raised.

ArgumentError

If initial is a Float, and the digits is larger than Float::DIG + 1, this exception is raised.

ArgumentError

If the initial is a Float or Rational, and the digits value is omitted, this exception is raised.

 
               static VALUE
f_BigDecimal(int argc, VALUE *argv, VALUE self)
{
    VALUE val, digs_v, opts = Qnil;
    argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts);
    int exception = opts_exception_p(opts);

    size_t digs = SIZE_MAX; /* this means digs is omitted */
    if (argc > 1) {
        digs_v = rb_to_int(digs_v);
        if (FIXNUM_P(digs_v)) {
            long n = FIX2LONG(digs_v);
            if (n < 0)
                goto negative_digs;
            digs = (size_t)n;
        }
        else {
            if (RBIGNUM_NEGATIVE_P(digs_v)) {
              negative_digs:
                if (!exception)
                    return Qnil;
                rb_raise(rb_eArgError, "negative precision");
            }
            digs = NUM2SIZET(digs_v);
        }
    }

    return rb_convert_to_BigDecimal(val, digs, exception);
}