class Float

A Float object represents a sometimes-inexact real number using the native architecture’s double-precision floating point representation.

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

You can create a Float object explicitly with:

You can convert certain objects to Floats with:

What’s Here

First, what’s elsewhere. Class Float:

Here, class Float provides methods for:

Querying

Comparing

Converting

Constants

DIG

The minimum number of significant decimal digits in a double-precision floating point.

Usually defaults to 15.

EPSILON

The difference between 1 and the smallest double-precision floating point number greater than 1.

Usually defaults to 2.2204460492503131e-16.

INFINITY

An expression representing positive infinity.

MANT_DIG

The number of base digits for the double data type.

Usually defaults to 53.

MAX

The largest possible integer in a double-precision floating point number.

Usually defaults to 1.7976931348623157e+308.

MAX_10_EXP

The largest positive exponent in a double-precision floating point where 10 raised to this power minus 1.

Usually defaults to 308.

MAX_EXP

The largest possible exponent value in a double-precision floating point.

Usually defaults to 1024.

MIN

The smallest positive normalized number in a double-precision floating point.

Usually defaults to 2.2250738585072014e-308.

If the platform supports denormalized numbers, there are numbers between zero and Float::MIN. 0.0.next_float returns the smallest positive floating point number including denormalized numbers.

MIN_10_EXP

The smallest negative exponent in a double-precision floating point where 10 raised to this power minus 1.

Usually defaults to -307.

MIN_EXP

The smallest possible exponent value in a double-precision floating point.

Usually defaults to -1021.

NAN

An expression representing a value which is “not a number”.

RADIX

The base of the floating point, or number of unique digits used to represent the number.

Usually defaults to 2 on most systems, which would represent a base-10 decimal.

Public Instance Methods

self % other → float click to toggle source

Returns self modulo other as a float.

For float f and real number r, these expressions are equivalent:

f % r
f-r*(f/r).floor
f.divmod(r)[1]

See Numeric#divmod.

Examples:

10.0 % 2              # => 0.0
10.0 % 3              # => 1.0
10.0 % 4              # => 2.0

10.0 % -2             # => 0.0
10.0 % -3             # => -2.0
10.0 % -4             # => -2.0

10.0 % 4.0            # => 2.0
10.0 % Rational(4, 1) # => 2.0
static VALUE
flo_mod(VALUE x, VALUE y)
{
    double fy;

    if (FIXNUM_P(y)) {
        fy = (double)FIX2LONG(y);
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        fy = rb_big2dbl(y);
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        fy = RFLOAT_VALUE(y);
    }
    else {
        return rb_num_coerce_bin(x, y, '%');
    }
    return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
}
Also aliased as: modulo
self * other → numeric click to toggle source

Returns a new Float which is the product of self and other:

f = 3.14
f * 2              # => 6.28
f * 2.0            # => 6.28
f * Rational(1, 2) # => 1.57
f * Complex(2, 0)  # => (6.28+0.0i)
VALUE
rb_float_mul(VALUE x, VALUE y)
{
    if (FIXNUM_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
    }
    else {
        return rb_num_coerce_bin(x, y, '*');
    }
}
self ** other → numeric click to toggle source

Raises self to the power of other:

f = 3.14
f ** 2              # => 9.8596
f ** -2             # => 0.1014239928597509
f ** 2.1            # => 11.054834900588839
f ** Rational(2, 1) # => 9.8596
f ** Complex(2, 0)  # => (9.8596+0i)
VALUE
rb_float_pow(VALUE x, VALUE y)
{
    double dx, dy;
    if (y == INT2FIX(2)) {
        dx = RFLOAT_VALUE(x);
        return DBL2NUM(dx * dx);
    }
    else if (FIXNUM_P(y)) {
        dx = RFLOAT_VALUE(x);
        dy = (double)FIX2LONG(y);
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        dx = RFLOAT_VALUE(x);
        dy = rb_big2dbl(y);
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        dx = RFLOAT_VALUE(x);
        dy = RFLOAT_VALUE(y);
        if (dx < 0 && dy != round(dy))
            return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
    }
    else {
        return rb_num_coerce_bin(x, y, idPow);
    }
    return DBL2NUM(pow(dx, dy));
}
self + other → numeric click to toggle source

Returns a new Float which is the sum of self and other:

f = 3.14
f + 1                 # => 4.140000000000001
f + 1.0               # => 4.140000000000001
f + Rational(1, 1)    # => 4.140000000000001
f + Complex(1, 0)     # => (4.140000000000001+0i)
VALUE
rb_float_plus(VALUE x, VALUE y)
{
    if (FIXNUM_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
    }
    else {
        return rb_num_coerce_bin(x, y, '+');
    }
}
self - other → numeric click to toggle source

Returns a new Float which is the difference of self and other:

f = 3.14
f - 1                 # => 2.14
f - 1.0               # => 2.14
f - Rational(1, 1)    # => 2.14
f - Complex(1, 0)     # => (2.14+0i)
VALUE
rb_float_minus(VALUE x, VALUE y)
{
    if (FIXNUM_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
    }
    else {
        return rb_num_coerce_bin(x, y, '-');
    }
}
-float → float click to toggle source

Returns self, negated.

# File numeric.rb, line 340
def -@
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_float_uminus(self)'
end
self / other → numeric click to toggle source

Returns a new Float which is the result of dividing self by other:

f = 3.14
f / 2              # => 1.57
f / 2.0            # => 1.57
f / Rational(2, 1) # => 1.57
f / Complex(2, 0)  # => (1.57+0.0i)
VALUE
rb_float_div(VALUE x, VALUE y)
{
    double num = RFLOAT_VALUE(x);
    double den;
    double ret;

    if (FIXNUM_P(y)) {
        den = FIX2LONG(y);
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        den = rb_big2dbl(y);
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        den = RFLOAT_VALUE(y);
    }
    else {
        return rb_num_coerce_bin(x, y, '/');
    }

    ret = double_div_double(num, den);
    return DBL2NUM(ret);
}
self < other → true or false click to toggle source

Returns true if self is numerically less than other:

2.0 < 3              # => true
2.0 < 3.0            # => true
2.0 < Rational(3, 1) # => true
2.0 < 2.0            # => false

Float::NAN < Float::NAN returns an implementation-dependent value.

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

    a = RFLOAT_VALUE(x);
    if (RB_INTEGER_TYPE_P(y)) {
        VALUE rel = rb_integer_float_cmp(y, x);
        if (FIXNUM_P(rel))
            return RBOOL(-FIX2LONG(rel) < 0);
        return Qfalse;
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(b)) return Qfalse;
#endif
    }
    else {
        return rb_num_coerce_relop(x, y, '<');
    }
#if MSC_VERSION_BEFORE(1300)
    if (isnan(a)) return Qfalse;
#endif
    return RBOOL(a < b);
}
self <= other → true or false click to toggle source

Returns true if self is numerically less than or equal to other:

2.0 <= 3              # => true
2.0 <= 3.0            # => true
2.0 <= Rational(3, 1) # => true
2.0 <= 2.0            # => true
2.0 <= 1.0            # => false

Float::NAN <= Float::NAN returns an implementation-dependent value.

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

    a = RFLOAT_VALUE(x);
    if (RB_INTEGER_TYPE_P(y)) {
        VALUE rel = rb_integer_float_cmp(y, x);
        if (FIXNUM_P(rel))
            return RBOOL(-FIX2LONG(rel) <= 0);
        return Qfalse;
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(b)) return Qfalse;
#endif
    }
    else {
        return rb_num_coerce_relop(x, y, idLE);
    }
#if MSC_VERSION_BEFORE(1300)
    if (isnan(a)) return Qfalse;
#endif
    return RBOOL(a <= b);
}
self <=> other → -1, 0, +1, or nil click to toggle source

Returns a value that depends on the numeric relation between self and other:

  • -1, if self is less than other.

  • 0, if self is equal to other.

  • 1, if self is greater than other.

  • nil, if the two values are incommensurate.

Examples:

2.0 <=> 2              # => 0
2.0 <=> 2.0            # => 0
2.0 <=> Rational(2, 1) # => 0
2.0 <=> Complex(2, 0)  # => 0
2.0 <=> 1.9            # => 1
2.0 <=> 2.1            # => -1
2.0 <=> 'foo'          # => nil

This is the basis for the tests in the Comparable module.

Float::NAN <=> Float::NAN returns an implementation-dependent value.

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

    a = RFLOAT_VALUE(x);
    if (isnan(a)) return Qnil;
    if (RB_INTEGER_TYPE_P(y)) {
        VALUE rel = rb_integer_float_cmp(y, x);
        if (FIXNUM_P(rel))
            return LONG2FIX(-FIX2LONG(rel));
        return rel;
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
    }
    else {
        if (isinf(a) && !UNDEF_P(i = rb_check_funcall(y, rb_intern("infinite?"), 0, 0))) {
            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, id_cmp);
    }
    return rb_dbl_cmp(a, b);
}
self == other → true or false click to toggle source

Returns true if other has the same value as self, false otherwise:

2.0 == 2              # => true
2.0 == 2.0            # => true
2.0 == Rational(2, 1) # => true
2.0 == Complex(2, 0)  # => true

Float::NAN == Float::NAN returns an implementation-dependent value.

Related: Float#eql? (requires other to be a Float).

VALUE
rb_float_equal(VALUE x, VALUE y)
{
    volatile double a, b;

    if (RB_INTEGER_TYPE_P(y)) {
        return rb_integer_float_eq(y, x);
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(b)) return Qfalse;
#endif
    }
    else {
        return num_equal(x, y);
    }
    a = RFLOAT_VALUE(x);
#if MSC_VERSION_BEFORE(1300)
    if (isnan(a)) return Qfalse;
#endif
    return RBOOL(a == b);
}
Also aliased as: ===
===
Alias for: ==
self > other → true or false click to toggle source

Returns true if self is numerically greater than other:

2.0 > 1              # => true
2.0 > 1.0            # => true
2.0 > Rational(1, 2) # => true
2.0 > 2.0            # => false

Float::NAN > Float::NAN returns an implementation-dependent value.

VALUE
rb_float_gt(VALUE x, VALUE y)
{
    double a, b;

    a = RFLOAT_VALUE(x);
    if (RB_INTEGER_TYPE_P(y)) {
        VALUE rel = rb_integer_float_cmp(y, x);
        if (FIXNUM_P(rel))
            return RBOOL(-FIX2LONG(rel) > 0);
        return Qfalse;
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(b)) return Qfalse;
#endif
    }
    else {
        return rb_num_coerce_relop(x, y, '>');
    }
#if MSC_VERSION_BEFORE(1300)
    if (isnan(a)) return Qfalse;
#endif
    return RBOOL(a > b);
}
self >= other → true or false click to toggle source

Returns true if self is numerically greater than or equal to other:

2.0 >= 1              # => true
2.0 >= 1.0            # => true
2.0 >= Rational(1, 2) # => true
2.0 >= 2.0            # => true
2.0 >= 2.1            # => false

Float::NAN >= Float::NAN returns an implementation-dependent value.

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

    a = RFLOAT_VALUE(x);
    if (RB_TYPE_P(y, T_FIXNUM) || RB_BIGNUM_TYPE_P(y)) {
        VALUE rel = rb_integer_float_cmp(y, x);
        if (FIXNUM_P(rel))
            return RBOOL(-FIX2LONG(rel) >= 0);
        return Qfalse;
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(b)) return Qfalse;
#endif
    }
    else {
        return rb_num_coerce_relop(x, y, idGE);
    }
#if MSC_VERSION_BEFORE(1300)
    if (isnan(a)) return Qfalse;
#endif
    return RBOOL(a >= b);
}
abs → float click to toggle source

Returns the absolute value of self:

(-34.56).abs # => 34.56
-34.56.abs   # => 34.56
34.56.abs    # => 34.56
# File numeric.rb, line 325
def abs
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_float_abs(self)'
end
angle
Alias for: arg
arg → 0 or Math::PI click to toggle source

Returns 0 if self is positive, Math::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);
}
Also aliased as: angle, phase
ceil(ndigits = 0) → float or integer click to toggle source

Returns the smallest number greater than or equal to self with a precision of ndigits decimal digits.

When ndigits is positive, returns a float with ndigits digits after the decimal point (as available):

f = 12345.6789
f.ceil(1) # => 12345.7
f.ceil(3) # => 12345.679
f = -12345.6789
f.ceil(1) # => -12345.6
f.ceil(3) # => -12345.678

When ndigits is non-positive, returns an integer with at least ndigits.abs trailing zeros:

f = 12345.6789
f.ceil(0)  # => 12346
f.ceil(-3) # => 13000
f = -12345.6789
f.ceil(0)  # => -12345
f.ceil(-3) # => -12000

Note that the limited precision of floating-point arithmetic may lead to surprising results:

(2.1 / 0.7).ceil  #=> 4 (!)

Related: Float#floor.

static VALUE
flo_ceil(int argc, VALUE *argv, VALUE num)
{
    int ndigits = flo_ndigits(argc, argv);
    return rb_float_ceil(num, ndigits);
}
coerce(other) → array click to toggle source

Returns a 2-element array containing other converted to a Float and self:

f = 3.14                 # => 3.14
f.coerce(2)              # => [2.0, 3.14]
f.coerce(2.0)            # => [2.0, 3.14]
f.coerce(Rational(1, 2)) # => [0.5, 3.14]
f.coerce(Complex(1, 0))  # => [1.0, 3.14]

Raises an exception if a type conversion fails.

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 also Float#numerator.

VALUE
rb_float_denominator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE r;
    if (!isfinite(d))
        return INT2FIX(1);
    r = float_to_r(self);
    return nurat_denominator(r);
}
divmod(other) → array click to toggle source

Returns a 2-element array [q, r], where

q = (self/other).floor      # Quotient
r = self % other            # Remainder

Examples:

11.0.divmod(4)              # => [2, 3.0]
11.0.divmod(-4)             # => [-3, -1.0]
-11.0.divmod(4)             # => [-3, 1.0]
-11.0.divmod(-4)            # => [2, -3.0]

12.0.divmod(4)              # => [3, 0.0]
12.0.divmod(-4)             # => [-3, 0.0]
-12.0.divmod(4)             # => [-3, -0.0]
-12.0.divmod(-4)            # => [3, -0.0]

13.0.divmod(4.0)            # => [3, 1.0]
13.0.divmod(Rational(4, 1)) # => [3, 1.0]
static VALUE
flo_divmod(VALUE x, VALUE y)
{
    double fy, div, mod;
    volatile VALUE a, b;

    if (FIXNUM_P(y)) {
        fy = (double)FIX2LONG(y);
    }
    else if (RB_BIGNUM_TYPE_P(y)) {
        fy = rb_big2dbl(y);
    }
    else if (RB_FLOAT_TYPE_P(y)) {
        fy = RFLOAT_VALUE(y);
    }
    else {
        return rb_num_coerce_bin(x, y, id_divmod);
    }
    flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
    a = dbl2ival(div);
    b = DBL2NUM(mod);
    return rb_assoc_new(a, b);
}
eql?(other) → true or false click to toggle source

Returns true if other is a Float with the same value as self, false otherwise:

2.0.eql?(2.0)            # => true
2.0.eql?(1.0)            # => false
2.0.eql?(1)              # => false
2.0.eql?(Rational(2, 1)) # => false
2.0.eql?(Complex(2, 0))  # => false

Float::NAN.eql?(Float::NAN) returns an implementation-dependent value.

Related: Float#== (performs type conversions).

VALUE
rb_float_eql(VALUE x, VALUE y)
{
    if (RB_FLOAT_TYPE_P(y)) {
        double a = RFLOAT_VALUE(x);
        double b = RFLOAT_VALUE(y);
#if MSC_VERSION_BEFORE(1300)
        if (isnan(a) || isnan(b)) return Qfalse;
#endif
    return RBOOL(a == b);
    }
    return Qfalse;
}
fdiv
Alias for: quo
finite? → true or false click to toggle source

Returns true if self is not Infinity, -Infinity, or NaN, false otherwise:

f = 2.0      # => 2.0
f.finite?    # => true
f = 1.0/0.0  # => Infinity
f.finite?    # => false
f = -1.0/0.0 # => -Infinity
f.finite?    # => false
f = 0.0/0.0  # => NaN
f.finite?    # => false
VALUE
rb_flo_is_finite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

    return RBOOL(isfinite(value));
}
floor(ndigits = 0) → float or integer click to toggle source

Returns the largest number less than or equal to self with a precision of ndigits decimal digits.

When ndigits is positive, returns a float with ndigits digits after the decimal point (as available):

f = 12345.6789
f.floor(1) # => 12345.6
f.floor(3) # => 12345.678
f = -12345.6789
f.floor(1) # => -12345.7
f.floor(3) # => -12345.679

When ndigits is non-positive, returns an integer with at least ndigits.abs trailing zeros:

f = 12345.6789
f.floor(0)  # => 12345
f.floor(-3) # => 12000
f = -12345.6789
f.floor(0)  # => -12346
f.floor(-3) # => -13000

Note that the limited precision of floating-point arithmetic may lead to surprising results:

(0.3 / 0.1).floor  #=> 2 (!)

Related: Float#ceil.

static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
    int ndigits = flo_ndigits(argc, argv);
    return rb_float_floor(num, ndigits);
}
hash → integer click to toggle source

Returns the integer hash value for self.

See also Object#hash.

static VALUE
flo_hash(VALUE num)
{
    return rb_dbl_hash(RFLOAT_VALUE(num));
}
infinite? → -1, 1, or nil click to toggle source

Returns:

  • 1, if self is Infinity.

  • -1 if self is -Infinity.

  • nil, otherwise.

Examples:

f = 1.0/0.0  # => Infinity
f.infinite?  # => 1
f = -1.0/0.0 # => -Infinity
f.infinite?  # => -1
f = 1.0      # => 1.0
f.infinite?  # => nil
f = 0.0/0.0  # => NaN
f.infinite?  # => nil
VALUE
rb_flo_is_infinite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

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

    return Qnil;
}
inspect
Alias for: to_s
magnitude() click to toggle source
# File numeric.rb, line 330
def magnitude
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_float_abs(self)'
end
modulo
Alias for: %
nan? → true or false click to toggle source

Returns true if self is a NaN, false otherwise.

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

    return RBOOL(isnan(value));
}
negative? → true or false click to toggle source

Returns true if self is less than 0, false otherwise.

# File numeric.rb, line 367
def negative?
  Primitive.attr! :leaf
  Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) < 0.0)'
end
next_float → float click to toggle source

Returns the next-larger representable Float.

These examples show the internally stored values (64-bit hexadecimal) for each Float f and for the corresponding f.next_float:

f = 0.0      # 0x0000000000000000
f.next_float # 0x0000000000000001

f = 0.01     # 0x3f847ae147ae147b
f.next_float # 0x3f847ae147ae147c

In the remaining examples here, the output is shown in the usual way (result to_s):

0.01.next_float    # => 0.010000000000000002
1.0.next_float     # => 1.0000000000000002
100.0.next_float   # => 100.00000000000001

f = 0.01
(0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.next_float }

Output:

 0 0x1.47ae147ae147bp-7 0.01
 1 0x1.47ae147ae147cp-7 0.010000000000000002
 2 0x1.47ae147ae147dp-7 0.010000000000000004
 3 0x1.47ae147ae147ep-7 0.010000000000000005

f = 0.0; 100.times { f += 0.1 }
f                           # => 9.99999999999998       # should be 10.0 in the ideal world.
10-f                        # => 1.9539925233402755e-14 # the floating point error.
10.0.next_float-10          # => 1.7763568394002505e-15 # 1 ulp (unit in the last place).
(10-f)/(10.0.next_float-10) # => 11.0                   # the error is 11 ulp.
(10-f)/(10*Float::EPSILON)  # => 8.8                    # approximation of the above.
"%a" % 10                   # => "0x1.4p+3"
"%a" % f                    # => "0x1.3fffffffffff5p+3" # the last hex digit is 5.  16 - 5 = 11 ulp.

Related: Float#prev_float

static VALUE
flo_next_float(VALUE vx)
{
    return flo_nextafter(vx, HUGE_VAL);
}
numerator → integer click to toggle source

Returns the numerator. The result is machine dependent.

n = 0.3.numerator    #=> 5404319552844595
d = 0.3.denominator  #=> 18014398509481984
n.fdiv(d)            #=> 0.3

See also Float#denominator.

VALUE
rb_float_numerator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE r;
    if (!isfinite(d))
        return self;
    r = float_to_r(self);
    return nurat_numerator(r);
}
phase
Alias for: arg
positive? → true or false click to toggle source

Returns true if self is greater than 0, false otherwise.

# File numeric.rb, line 358
def positive?
  Primitive.attr! :leaf
  Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) > 0.0)'
end
prev_float → float click to toggle source

Returns the next-smaller representable Float.

These examples show the internally stored values (64-bit hexadecimal) for each Float f and for the corresponding f.pev_float:

f = 5e-324   # 0x0000000000000001
f.prev_float # 0x0000000000000000

f = 0.01     # 0x3f847ae147ae147b
f.prev_float # 0x3f847ae147ae147a

In the remaining examples here, the output is shown in the usual way (result to_s):

0.01.prev_float   # => 0.009999999999999998
1.0.prev_float    # => 0.9999999999999999
100.0.prev_float  # => 99.99999999999999

f = 0.01
(0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.prev_float }

Output:

0 0x1.47ae147ae147bp-7 0.01
1 0x1.47ae147ae147ap-7 0.009999999999999998
2 0x1.47ae147ae1479p-7 0.009999999999999997
3 0x1.47ae147ae1478p-7 0.009999999999999995

Related: Float#next_float.

static VALUE
flo_prev_float(VALUE vx)
{
    return flo_nextafter(vx, -HUGE_VAL);
}
quo(other) → numeric click to toggle source

Returns the quotient from dividing self by other:

f = 3.14
f.quo(2)              # => 1.57
f.quo(-2)             # => -1.57
f.quo(Rational(2, 1)) # => 1.57
f.quo(Complex(2, 0))  # => (1.57+0.0i)
static VALUE
flo_quo(VALUE x, VALUE y)
{
    return num_funcall1(x, '/', y);
}
Also aliased as: fdiv
rationalize([eps]) → rational click to toggle source

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

0.3.rationalize          #=> (3/10)
1.333.rationalize        #=> (1333/1000)
1.333.rationalize(0.01)  #=> (4/3)

See also Float#to_r.

static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE rat;
    int neg = d < 0.0;
    if (neg) self = DBL2NUM(-d);

    if (rb_check_arity(argc, 0, 1)) {
        rat = rb_flt_rationalize_with_prec(self, argv[0]);
    }
    else {
        rat = rb_flt_rationalize(self);
    }
    if (neg) RATIONAL_SET_NUM(rat, rb_int_uminus(RRATIONAL(rat)->num));
    return rat;
}
round(ndigits = 0, half: :up]) → integer or float click to toggle source

Returns self rounded to the nearest value with a precision of ndigits decimal digits.

When ndigits is non-negative, returns a float with ndigits after the decimal point (as available):

f = 12345.6789
f.round(1) # => 12345.7
f.round(3) # => 12345.679
f = -12345.6789
f.round(1) # => -12345.7
f.round(3) # => -12345.679

When ndigits is negative, returns an integer with at least ndigits.abs trailing zeros:

f = 12345.6789
f.round(0)  # => 12346
f.round(-3) # => 12000
f = -12345.6789
f.round(0)  # => -12346
f.round(-3) # => -12000

If keyword argument half is given, and self is equidistant from the two candidate values, the rounding is according to the given half value:

  • :up or nil: round away from zero:

    2.5.round(half: :up)      # => 3
    3.5.round(half: :up)      # => 4
    (-2.5).round(half: :up)   # => -3
    
  • :down: round toward zero:

    2.5.round(half: :down)    # => 2
    3.5.round(half: :down)    # => 3
    (-2.5).round(half: :down) # => -2
    
  • :even: round toward the candidate whose last nonzero digit is even:

    2.5.round(half: :even)    # => 2
    3.5.round(half: :even)    # => 4
    (-2.5).round(half: :even) # => -2
    

Raises and exception if the value for half is invalid.

Related: Float#truncate.

static VALUE
flo_round(int argc, VALUE *argv, VALUE num)
{
    double number, f, x;
    VALUE nd, opt;
    int ndigits = 0;
    enum ruby_num_rounding_mode mode;

    if (rb_scan_args(argc, argv, "01:", &nd, &opt)) {
        ndigits = NUM2INT(nd);
    }
    mode = rb_num_get_rounding_option(opt);
    number = RFLOAT_VALUE(num);
    if (number == 0.0) {
        return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
    }
    if (ndigits < 0) {
        return rb_int_round(flo_to_i(num), ndigits, mode);
    }
    if (ndigits == 0) {
        x = ROUND_CALL(mode, round, (number, 1.0));
        return dbl2ival(x);
    }
    if (isfinite(number)) {
        int binexp;
        frexp(number, &binexp);
        if (float_round_overflow(ndigits, binexp)) return num;
        if (float_round_underflow(ndigits, binexp)) return DBL2NUM(0);
        if (ndigits > 14) {
            /* In this case, pow(10, ndigits) may not be accurate. */
            return rb_flo_round_by_rational(argc, argv, num);
        }
        f = pow(10, ndigits);
        x = ROUND_CALL(mode, round, (number, f));
        return DBL2NUM(x / f);
    }
    return num;
}
to_d → bigdecimal click to toggle source
to_d(precision) → bigdecimal

Returns the value of float as a BigDecimal. The precision parameter is used to determine the number of significant digits for the result. When precision is set to 0, the number of digits to represent the float being converted is determined automatically. The default precision is 0.

require 'bigdecimal'
require 'bigdecimal/util'

0.5.to_d         # => 0.5e0
1.234.to_d       # => 0.1234e1
1.234.to_d(2)    # => 0.12e1

See also Kernel.BigDecimal.

# File ext/bigdecimal/lib/bigdecimal/util.rb, line 50
def to_d(precision=0)
  BigDecimal(self, precision)
end
to_f → self click to toggle source

Returns self (which is already a Float).

# File numeric.rb, line 312
def to_f
  self
end
to_i → integer click to toggle source

Returns self truncated to an Integer.

1.2.to_i    # => 1
(-1.2).to_i # => -1

Note that the limited precision of floating-point arithmetic may lead to surprising results:

(0.3 / 0.1).to_i  # => 2 (!)
static VALUE
flo_to_i(VALUE num)
{
    double f = RFLOAT_VALUE(num);

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

    return dbl2ival(f);
}
Also aliased as: to_int
to_int
Alias for: to_i
to_r → rational click to toggle source

Returns the value as a rational.

2.0.to_r    #=> (2/1)
2.5.to_r    #=> (5/2)
-0.75.to_r  #=> (-3/4)
0.0.to_r    #=> (0/1)
0.3.to_r    #=> (5404319552844595/18014398509481984)

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.

0.3.to_r   == 3/10r  #=> false
"0.3".to_r == 3/10r  #=> true

See also Float#rationalize.

static VALUE
float_to_r(VALUE self)
{
    VALUE f;
    int n;

    float_decode_internal(self, &f, &n);
#if FLT_RADIX == 2
    if (n == 0)
        return rb_rational_new1(f);
    if (n > 0)
        return rb_rational_new1(rb_int_lshift(f, INT2FIX(n)));
    n = -n;
    return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(n)));
#else
    f = rb_int_mul(f, rb_int_pow(INT2FIX(FLT_RADIX), n));
    if (RB_TYPE_P(f, T_RATIONAL))
        return f;
    return rb_rational_new1(f);
#endif
}
to_s → string click to toggle source

Returns a string containing a representation of self; depending of the value of self, the string representation may contain:

  • A fixed-point number.

  • A number in “scientific notation” (containing an exponent).

  • ‘Infinity’.

  • ‘-Infinity’.

  • ‘NaN’ (indicating not-a-number).

    3.14.to_s # => “3.14” (10.1**50).to_s # => “1.644631821843879e+50” (10.1**500).to_s # => “Infinity” (-10.1**500).to_s # => “-Infinity” (0.0/0.0).to_s # => “NaN”

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

    if (isinf(value)) {
        static const char minf[] = "-Infinity";
        const int pos = (value > 0); /* skip "-" */
        return rb_usascii_str_new(minf+pos, strlen(minf)-pos);
    }
    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);
    free(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 <= DBL_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 {
        goto exp;
    }
    return s;

  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;
}
Also aliased as: inspect
truncate(ndigits = 0) → float or integer click to toggle source

Returns self truncated (toward zero) to a precision of ndigits decimal digits.

When ndigits is positive, returns a float with ndigits digits after the decimal point (as available):

f = 12345.6789
f.truncate(1) # => 12345.6
f.truncate(3) # => 12345.678
f = -12345.6789
f.truncate(1) # => -12345.6
f.truncate(3) # => -12345.678

When ndigits is negative, returns an integer with at least ndigits.abs trailing zeros:

f = 12345.6789
f.truncate(0)  # => 12345
f.truncate(-3) # => 12000
f = -12345.6789
f.truncate(0)  # => -12345
f.truncate(-3) # => -12000

Note that the limited precision of floating-point arithmetic may lead to surprising results:

(0.3 / 0.1).truncate  #=> 2 (!)

Related: Float#round.

static VALUE
flo_truncate(int argc, VALUE *argv, VALUE num)
{
    if (signbit(RFLOAT_VALUE(num)))
        return flo_ceil(argc, argv, num);
    else
        return flo_floor(argc, argv, num);
}
zero? → true or false click to toggle source

Returns true if self is 0.0, false otherwise.

# File numeric.rb, line 349
def zero?
  Primitive.attr! :leaf
  Primitive.cexpr! 'RBOOL(FLOAT_ZERO_P(self))'
end