Float

Float objects represent inexact real numbers using the native architecture's double-precision floating point representation.

Floating point has a different arithmetic and is a inexact number. So you should know its esoteric system. see following:

Public Instance Methods

flt % other → float click to toggle source
modulo(other) → float

Return the modulo after division of flt by other.

6543.21.modulo(137)      #=> 104.21
6543.21.modulo(137.24)   #=> 92.9299999999996
 
               static VALUE
flo_mod(VALUE x, VALUE y)
{
    double fy;

    switch (TYPE(y)) {
      case T_FIXNUM:
        fy = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        fy = rb_big2dbl(y);
        break;
      case T_FLOAT:
        fy = RFLOAT_VALUE(y);
        break;
      default:
        return rb_num_coerce_bin(x, y, '%');
    }
    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
}
            
float * other → float click to toggle source

Returns a new float which is the product of float and other.

 
               static VALUE
flo_mul(VALUE x, VALUE y)
{
    switch (TYPE(y)) {
      case T_FIXNUM:
        return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
      case T_BIGNUM:
        return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
      case T_FLOAT:
        return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
      default:
        return rb_num_coerce_bin(x, y, '*');
    }
}
            
flt ** other → float click to toggle source

Raises float the other power.

2.0**3      #=> 8.0
 
               static VALUE
flo_pow(VALUE x, VALUE y)
{
    switch (TYPE(y)) {
      case T_FIXNUM:
        return DBL2NUM(pow(RFLOAT_VALUE(x), (double)FIX2LONG(y)));
      case T_BIGNUM:
        return DBL2NUM(pow(RFLOAT_VALUE(x), rb_big2dbl(y)));
      case T_FLOAT:
        {
            double dx = RFLOAT_VALUE(x);
            double dy = RFLOAT_VALUE(y);
            if (dx < 0 && dy != round(dy))
                return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
            return DBL2NUM(pow(dx, dy));
        }
      default:
        return rb_num_coerce_bin(x, y, rb_intern("**"));
    }
}
            
float + other → float click to toggle source

Returns a new float which is the sum of float and other.

 
               static VALUE
flo_plus(VALUE x, VALUE y)
{
    switch (TYPE(y)) {
      case T_FIXNUM:
        return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
      case T_BIGNUM:
        return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
      case T_FLOAT:
        return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
      default:
        return rb_num_coerce_bin(x, y, '+');
    }
}
            
float - other → float click to toggle source

Returns a new float which is the difference of float and other.

 
               static VALUE
flo_minus(VALUE x, VALUE y)
{
    switch (TYPE(y)) {
      case T_FIXNUM:
        return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
      case T_BIGNUM:
        return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
      case T_FLOAT:
        return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
      default:
        return rb_num_coerce_bin(x, y, '-');
    }
}
            
-float → float click to toggle source

Returns float, negated.

 
               static VALUE
flo_uminus(VALUE flt)
{
    return DBL2NUM(-RFLOAT_VALUE(flt));
}
            
float / other → float click to toggle source

Returns a new float which is the result of dividing float by other.

 
               static VALUE
flo_div(VALUE x, VALUE y)
{
    long f_y;
    double d;

    switch (TYPE(y)) {
      case T_FIXNUM:
        f_y = FIX2LONG(y);
        return DBL2NUM(RFLOAT_VALUE(x) / (double)f_y);
      case T_BIGNUM:
        d = rb_big2dbl(y);
        return DBL2NUM(RFLOAT_VALUE(x) / d);
      case T_FLOAT:
        return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
      default:
        return rb_num_coerce_bin(x, y, '/');
    }
}
            
flt < real → true or false click to toggle source

true if flt is less than real.

 
               static VALUE
flo_lt(VALUE x, VALUE y)
{
    double a, b;

    a = RFLOAT_VALUE(x);
    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;

      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;

      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;

      default:
        return rb_num_coerce_relop(x, y, '<');
    }
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a < b)?Qtrue:Qfalse;
}
            
flt <= real → true or false click to toggle source

true if flt is less than or equal to real.

 
               static VALUE
flo_le(VALUE x, VALUE y)
{
    double a, b;

    a = RFLOAT_VALUE(x);
    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;

      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;

      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;

      default:
        return rb_num_coerce_relop(x, y, rb_intern("<="));
    }
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a <= b)?Qtrue:Qfalse;
}
            
flt <=> real → -1, 0, +1 or nil click to toggle source

Returns -1, 0, +1 or nil depending on whether flt is less than, equal to, or greater than real. This is the basis for the tests in Comparable.

 
               static VALUE
flo_cmp(VALUE x, VALUE y)
{
    double a, b;
    VALUE i;

    a = RFLOAT_VALUE(x);
    if (isnan(a)) return Qnil;
    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;

      case T_BIGNUM:
        if (isinf(a)) {
            if (a > 0.0) return INT2FIX(1);
            else return INT2FIX(-1);
        }
        b = rb_big2dbl(y);
        break;

      case T_FLOAT:
        b = RFLOAT_VALUE(y);
        break;

      default:
        if (isinf(a) && (i = rb_check_funcall(y, rb_intern("infinite?"), 0, 0)) != Qundef) {
            if (RTEST(i)) {
                int j = rb_cmpint(i, x, y);
                j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
                return INT2FIX(j);
            }
            if (a > 0.0) return INT2FIX(1);
            return INT2FIX(-1);
        }
        return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
    }
    return rb_dbl_cmp(a, b);
}
            
flt == obj → true or false click to toggle source

Returns true only if obj has the same value as flt. Contrast this with Float#eql?, which requires obj to be a Float.

1.0 == 1   #=> true
 
               static VALUE
flo_eq(VALUE x, VALUE y)
{
    volatile double a, b;

    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;
      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;
      default:
        return num_equal(x, y);
    }
    a = RFLOAT_VALUE(x);
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a == b)?Qtrue:Qfalse;
}
            
flt == obj → true or false click to toggle source

Returns true only if obj has the same value as flt. Contrast this with Float#eql?, which requires obj to be a Float.

1.0 == 1   #=> true
 
               static VALUE
flo_eq(VALUE x, VALUE y)
{
    volatile double a, b;

    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;
      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;
      default:
        return num_equal(x, y);
    }
    a = RFLOAT_VALUE(x);
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a == b)?Qtrue:Qfalse;
}
            
flt > real → true or false click to toggle source

true if flt is greater than real.

 
               static VALUE
flo_gt(VALUE x, VALUE y)
{
    double a, b;

    a = RFLOAT_VALUE(x);
    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;

      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;

      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;

      default:
        return rb_num_coerce_relop(x, y, '>');
    }
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a > b)?Qtrue:Qfalse;
}
            
flt >= real → true or false click to toggle source

true if flt is greater than or equal to real.

 
               static VALUE
flo_ge(VALUE x, VALUE y)
{
    double a, b;

    a = RFLOAT_VALUE(x);
    switch (TYPE(y)) {
      case T_FIXNUM:
        b = (double)FIX2LONG(y);
        break;

      case T_BIGNUM:
        b = rb_big2dbl(y);
        break;

      case T_FLOAT:
        b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(b)) return Qfalse;
#endif
        break;

      default:
        return rb_num_coerce_relop(x, y, rb_intern(">="));
    }
#if defined(_MSC_VER) && _MSC_VER < 1300
    if (isnan(a)) return Qfalse;
#endif
    return (a >= b)?Qtrue:Qfalse;
}
            
abs → float click to toggle source
magnitude → float

Returns the absolute value of flt.

(-34.56).abs   #=> 34.56
-34.56.abs     #=> 34.56
 
               static VALUE
flo_abs(VALUE flt)
{
    double val = fabs(RFLOAT_VALUE(flt));
    return DBL2NUM(val);
}
            
arg → 0 or float click to toggle source
angle → 0 or float
phase → 0 or float

Returns 0 if the value is positive, pi otherwise.

 
               static VALUE
float_arg(VALUE self)
{
    if (isnan(RFLOAT_VALUE(self)))
        return self;
    if (f_tpositive_p(self))
        return INT2FIX(0);
    return rb_const_get(rb_mMath, id_PI);
}
            
arg → 0 or float click to toggle source
angle → 0 or float
phase → 0 or float

Returns 0 if the value is positive, pi otherwise.

 
               static VALUE
float_arg(VALUE self)
{
    if (isnan(RFLOAT_VALUE(self)))
        return self;
    if (f_tpositive_p(self))
        return INT2FIX(0);
    return rb_const_get(rb_mMath, id_PI);
}
            
ceil → integer click to toggle source

Returns the smallest Integer greater than or equal to flt.

1.2.ceil      #=> 2
2.0.ceil      #=> 2
(-1.2).ceil   #=> -1
(-2.0).ceil   #=> -2
 
               static VALUE
flo_ceil(VALUE num)
{
    double f = ceil(RFLOAT_VALUE(num));
    long val;

    if (!FIXABLE(f)) {
        return rb_dbl2big(f);
    }
    val = (long)f;
    return LONG2FIX(val);
}
            
coerce(numeric) → array click to toggle source

Returns an array with both aNumeric and flt represented as Float objects. This is achieved by converting aNumeric to a Float.

1.2.coerce(3)       #=> [3.0, 1.2]
2.5.coerce(1.1)     #=> [1.1, 2.5]
 
               static VALUE
flo_coerce(VALUE x, VALUE y)
{
    return rb_assoc_new(rb_Float(y), x);
}
            
denominator → integer click to toggle source

Returns the denominator (always positive). The result is machine dependent.

See numerator.

 
               static VALUE
float_denominator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    if (isinf(d) || isnan(d))
        return INT2FIX(1);
    return rb_call_super(0, 0);
}
            
divmod(numeric) → array click to toggle source

See Numeric#divmod.

 
               static VALUE
flo_divmod(VALUE x, VALUE y)
{
    double fy, div, mod;
    volatile VALUE a, b;

    switch (TYPE(y)) {
      case T_FIXNUM:
        fy = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        fy = rb_big2dbl(y);
        break;
      case T_FLOAT:
        fy = RFLOAT_VALUE(y);
        break;
      default:
        return rb_num_coerce_bin(x, y, rb_intern("divmod"));
    }
    flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
    a = dbl2ival(div);
    b = DBL2NUM(mod);
    return rb_assoc_new(a, b);
}
            
eql?(obj) → true or false click to toggle source

Returns true only if obj is a Float with the same value as flt. Contrast this with Float#==, which performs type conversions.

1.0.eql?(1)   #=> false
 
               static VALUE
flo_eql(VALUE x, VALUE y)
{
    if (TYPE(y) == T_FLOAT) {
        double a = RFLOAT_VALUE(x);
        double b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
        if (isnan(a) || isnan(b)) return Qfalse;
#endif
        if (a == b)
            return Qtrue;
    }
    return Qfalse;
}
            
quo(numeric) → float click to toggle source

Returns float / numeric.

 
               static VALUE
flo_quo(VALUE x, VALUE y)
{
    return rb_funcall(x, '/', 1, y);
}
            
finite? → true or false click to toggle source

Returns true if flt is a valid IEEE floating point number (it is not infinite, and nan? is false).

 
               static VALUE
flo_is_finite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

#if HAVE_FINITE
    if (!finite(value))
        return Qfalse;
#else
    if (isinf(value) || isnan(value))
        return Qfalse;
#endif

    return Qtrue;
}
            
floor → integer click to toggle source

Returns the largest integer less than or equal to flt.

1.2.floor      #=> 1
2.0.floor      #=> 2
(-1.2).floor   #=> -2
(-2.0).floor   #=> -2
 
               static VALUE
flo_floor(VALUE num)
{
    double f = floor(RFLOAT_VALUE(num));
    long val;

    if (!FIXABLE(f)) {
        return rb_dbl2big(f);
    }
    val = (long)f;
    return LONG2FIX(val);
}
            
hash → integer click to toggle source

Returns a hash code for this float.

 
               static VALUE
flo_hash(VALUE num)
{
    double d;
    st_index_t hash;

    d = RFLOAT_VALUE(num);
    /* normalize -0.0 to 0.0 */
    if (d == 0.0) d = 0.0;
    hash = rb_memhash(&d, sizeof(d));
    return LONG2FIX(hash);
}
            
infinite? → nil, -1, +1 click to toggle source

Returns nil, -1, or +1 depending on whether flt is finite, -infinity, or +infinity.

(0.0).infinite?        #=> nil
(-1.0/0.0).infinite?   #=> -1
(+1.0/0.0).infinite?   #=> 1
 
               static VALUE
flo_is_infinite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

    if (isinf(value)) {
        return INT2FIX( value < 0 ? -1 : 1 );
    }

    return Qnil;
}
            
abs → float click to toggle source
magnitude → float

Returns the absolute value of flt.

(-34.56).abs   #=> 34.56
-34.56.abs     #=> 34.56
 
               static VALUE
flo_abs(VALUE flt)
{
    double val = fabs(RFLOAT_VALUE(flt));
    return DBL2NUM(val);
}
            
flt % other → float click to toggle source
modulo(other) → float

Return the modulo after division of flt by other.

6543.21.modulo(137)      #=> 104.21
6543.21.modulo(137.24)   #=> 92.9299999999996
 
               static VALUE
flo_mod(VALUE x, VALUE y)
{
    double fy;

    switch (TYPE(y)) {
      case T_FIXNUM:
        fy = (double)FIX2LONG(y);
        break;
      case T_BIGNUM:
        fy = rb_big2dbl(y);
        break;
      case T_FLOAT:
        fy = RFLOAT_VALUE(y);
        break;
      default:
        return rb_num_coerce_bin(x, y, '%');
    }
    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
}
            
nan? → true or false click to toggle source

Returns true if flt is an invalid IEEE floating point number.

a = -1.0      #=> -1.0
a.nan?        #=> false
a = 0.0/0.0   #=> NaN
a.nan?        #=> true
 
               static VALUE
flo_is_nan_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

    return isnan(value) ? Qtrue : Qfalse;
}
            
numerator → integer click to toggle source

Returns the numerator. The result is machine dependent.

For example:

n = 0.3.numerator    #=> 5404319552844595
d = 0.3.denominator  #=> 18014398509481984
n.fdiv(d)            #=> 0.3
 
               static VALUE
float_numerator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    if (isinf(d) || isnan(d))
        return self;
    return rb_call_super(0, 0);
}
            
arg → 0 or float click to toggle source
angle → 0 or float
phase → 0 or float

Returns 0 if the value is positive, pi otherwise.

 
               static VALUE
float_arg(VALUE self)
{
    if (isnan(RFLOAT_VALUE(self)))
        return self;
    if (f_tpositive_p(self))
        return INT2FIX(0);
    return rb_const_get(rb_mMath, id_PI);
}
            
quo(numeric) → float click to toggle source

Returns float / numeric.

 
               static VALUE
flo_quo(VALUE x, VALUE y)
{
    return rb_funcall(x, '/', 1, y);
}
            
rationalize([eps]) → rational click to toggle source

Returns a simpler approximation of the value (flt-|eps| <= result <= flt+|eps|). if eps is not given, it will be chosen automatically.

For example:

0.3.rationalize          #=> (3/10)
1.333.rationalize        #=> (1333/1000)
1.333.rationalize(0.01)  #=> (4/3)
 
               static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
    VALUE e, a, b, p, q;

    if (f_negative_p(self))
        return f_negate(float_rationalize(argc, argv, f_abs(self)));

    rb_scan_args(argc, argv, "01", &e);

    if (argc != 0) {
        e = f_abs(e);
        a = f_sub(self, e);
        b = f_add(self, e);
    }
    else {
        VALUE f, n;

        float_decode_internal(self, &f, &n);
        if (f_zero_p(f) || f_positive_p(n))
            return rb_rational_new1(f_lshift(f, n));

#if FLT_RADIX == 2
        a = rb_rational_new2(f_sub(f_mul(TWO, f), ONE),
                             f_lshift(ONE, f_sub(ONE, n)));
        b = rb_rational_new2(f_add(f_mul(TWO, f), ONE),
                             f_lshift(ONE, f_sub(ONE, n)));
#else
        a = rb_rational_new2(f_sub(f_mul(INT2FIX(FLT_RADIX), f),
                                   INT2FIX(FLT_RADIX - 1)),
                             f_expt(INT2FIX(FLT_RADIX), f_sub(ONE, n)));
        b = rb_rational_new2(f_add(f_mul(INT2FIX(FLT_RADIX), f),
                                   INT2FIX(FLT_RADIX - 1)),
                             f_expt(INT2FIX(FLT_RADIX), f_sub(ONE, n)));
#endif
    }

    if (f_eqeq_p(a, b))
        return f_to_r(self);

    nurat_rationalize_internal(a, b, &p, &q);
    return rb_rational_new2(p, q);
}
            
round([ndigits]) → integer or float click to toggle source

Rounds flt to a given precision in decimal digits (default 0 digits). Precision may be negative. Returns a floating point number when ndigits is more than zero.

1.4.round      #=> 1
1.5.round      #=> 2
1.6.round      #=> 2
(-1.5).round   #=> -2

1.234567.round(2)  #=> 1.23
1.234567.round(3)  #=> 1.235
1.234567.round(4)  #=> 1.2346
1.234567.round(5)  #=> 1.23457

34567.89.round(-5) #=> 0
34567.89.round(-4) #=> 30000
34567.89.round(-3) #=> 35000
34567.89.round(-2) #=> 34600
34567.89.round(-1) #=> 34570
34567.89.round(0)  #=> 34568
34567.89.round(1)  #=> 34567.9
34567.89.round(2)  #=> 34567.89
34567.89.round(3)  #=> 34567.89
 
               static VALUE
flo_round(int argc, VALUE *argv, VALUE num)
{
    VALUE nd;
    double number, f;
    int ndigits = 0;
    int binexp;
    enum {float_dig = DBL_DIG+2};

    if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {
        ndigits = NUM2INT(nd);
    }
    if (ndigits < 0) {
        return int_round_0(flo_truncate(num), ndigits);
    }
    number  = RFLOAT_VALUE(num);
    if (ndigits == 0) {
        return dbl2ival(number);
    }
    frexp(number, &binexp);

/* Let `exp` be such that `number` is written as:"0.#{digits}e#{exp}",
   i.e. such that  10 ** (exp - 1) <= |number| < 10 ** exp
   Recall that up to float_dig digits can be needed to represent a double,
   so if ndigits + exp >= float_dig, the intermediate value (number * 10 ** ndigits)
   will be an integer and thus the result is the original number.
   If ndigits + exp <= 0, the result is 0 or "1e#{exp}", so
   if ndigits + exp < 0, the result is 0.
   We have:
        2 ** (binexp-1) <= |number| < 2 ** binexp
        10 ** ((binexp-1)/log_2(10)) <= |number| < 10 ** (binexp/log_2(10))
        If binexp >= 0, and since log_2(10) = 3.322259:
           10 ** (binexp/4 - 1) < |number| < 10 ** (binexp/3)
           floor(binexp/4) <= exp <= ceil(binexp/3)
        If binexp <= 0, swap the /4 and the /3
        So if ndigits + floor(binexp/(4 or 3)) >= float_dig, the result is number
        If ndigits + ceil(binexp/(3 or 4)) < 0 the result is 0
*/
    if (isinf(number) || isnan(number) ||
        (ndigits >= float_dig - (binexp > 0 ? binexp / 4 : binexp / 3 - 1))) {
        return num;
    }
    if (ndigits < - (binexp > 0 ? binexp / 3 + 1 : binexp / 4)) {
        return DBL2NUM(0);
    }
    f = pow(10, ndigits);
    return DBL2NUM(round(number * f) / f);
}
            
to_f → self click to toggle source

As flt is already a float, returns self.

 
               static VALUE
flo_to_f(VALUE num)
{
    return num;
}
            
to_i → integer click to toggle source
to_int → integer
truncate → integer

Returns flt truncated to an Integer.

 
               static VALUE
flo_truncate(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    long val;

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    if (!FIXABLE(f)) {
        return rb_dbl2big(f);
    }
    val = (long)f;
    return LONG2FIX(val);
}
            
to_i → integer click to toggle source
to_int → integer
truncate → integer

Returns flt truncated to an Integer.

 
               static VALUE
flo_truncate(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    long val;

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    if (!FIXABLE(f)) {
        return rb_dbl2big(f);
    }
    val = (long)f;
    return LONG2FIX(val);
}
            
to_r → rational click to toggle source

Returns the value as a rational.

NOTE: 0.3.to_r isn’t the same as ‘0.3’.to_r. The latter is equivalent to ‘3/10’.#to_r, but the former isn’t so.

For example:

2.0.to_r    #=> (2/1)
2.5.to_r    #=> (5/2)
-0.75.to_r  #=> (-3/4)
0.0.to_r    #=> (0/1)
 
               static VALUE
float_to_r(VALUE self)
{
    VALUE f, n;

    float_decode_internal(self, &f, &n);
#if FLT_RADIX == 2
    {
        long ln = FIX2LONG(n);

        if (ln == 0)
            return f_to_r(f);
        if (ln > 0)
            return f_to_r(f_lshift(f, n));
        ln = -ln;
        return rb_rational_new2(f, f_lshift(ONE, INT2FIX(ln)));
    }
#else
    return f_to_r(f_mul(f, f_expt(INT2FIX(FLT_RADIX), n)));
#endif
}
            
to_s → string click to toggle source

Returns a string containing a representation of self. As well as a fixed or exponential form of the number, the call may return “NaN”, “Infinity”, and “-Infinity”.

 
               static VALUE
flo_to_s(VALUE flt)
{
    char *ruby_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve);
    enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
    enum {float_dig = DBL_DIG+1};
    char buf[float_dig + (decimal_mant + CHAR_BIT - 1) / CHAR_BIT + 10];
    double value = RFLOAT_VALUE(flt);
    VALUE s;
    char *p, *e;
    int sign, decpt, digs;

    if (isinf(value))
        return rb_usascii_str_new2(value < 0 ? "-Infinity" : "Infinity");
    else if (isnan(value))
        return rb_usascii_str_new2("NaN");

    p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
    s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
    if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
    memcpy(buf, p, digs);
    xfree(p);
    if (decpt > 0) {
        if (decpt < digs) {
            memmove(buf + decpt + 1, buf + decpt, digs - decpt);
            buf[decpt] = '.';
            rb_str_cat(s, buf, digs + 1);
        }
        else if (decpt - digs < float_dig) {
            long len;
            char *ptr;
            rb_str_cat(s, buf, digs);
            rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
            ptr = RSTRING_PTR(s) + len;
            if (decpt > digs) {
                memset(ptr, '0', decpt - digs);
                ptr += decpt - digs;
            }
            memcpy(ptr, ".0", 2);
        }
        else {
            goto exp;
        }
    }
    else if (decpt > -4) {
        long len;
        char *ptr;
        rb_str_cat(s, "0.", 2);
        rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
        ptr = RSTRING_PTR(s);
        memset(ptr += len, '0', -decpt);
        memcpy(ptr -= decpt, buf, digs);
    }
    else {
      exp:
        if (digs > 1) {
            memmove(buf + 2, buf + 1, digs - 1);
        }
        else {
            buf[2] = '0';
            digs++;
        }
        buf[1] = '.';
        rb_str_cat(s, buf, digs + 1);
        rb_str_catf(s, "e%+03d", decpt - 1);
    }
    return s;
}
            
to_i → integer click to toggle source
to_int → integer
truncate → integer

Returns flt truncated to an Integer.

 
               static VALUE
flo_truncate(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    long val;

    if (f > 0.0) f = floor(f);
    if (f < 0.0) f = ceil(f);

    if (!FIXABLE(f)) {
        return rb_dbl2big(f);
    }
    val = (long)f;
    return LONG2FIX(val);
}
            
zero? → true or false click to toggle source

Returns true if flt is 0.0.

 
               static VALUE
flo_zero_p(VALUE num)
{
    if (RFLOAT_VALUE(num) == 0.0) {
        return Qtrue;
    }
    return Qfalse;
}
            

Commenting is here to help enhance the documentation. For example, sample code, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

blog comments powered by Disqus