• complex.c
• numeric.c
• rational.c

Quicksearch

# 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 an inexact number. So you should know its esoteric system. see following:

### 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 posable exponent value in a double-precision floating point.

Usually defaults to -1021.

NAN

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

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.

ROUNDS

Represents the rounding mode for floating point addition.

Usually defaults to 1, rounding to the nearest number.

Other modes include:

-1

Indeterminable

0

Rounding towards zero

1

Rounding to the nearest number

2

Rounding towards positive infinity

3

Rounding towards negative infinity

### Public Instance Methods

float % other → float click to toggle source

Return the modulo after division of `float` 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;

if (RB_TYPE_P(y, T_FIXNUM)) {
fy = (double)FIX2LONG(y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
fy = rb_big2dbl(y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
fy = RFLOAT_VALUE(y);
}
else {
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)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '*');
}
}
```
float ** other → float click to toggle source

Raises `float` to the power of `other`.

```2.0**3      #=> 8.0
```
```
static VALUE
flo_pow(VALUE x, VALUE y)
{
double dx, dy;
if (RB_TYPE_P(y, T_FIXNUM)) {
dx = RFLOAT_VALUE(x);
dy = (double)FIX2LONG(y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
dx = RFLOAT_VALUE(x);
dy = rb_big2dbl(y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
dx = RFLOAT_VALUE(x);
dy = RFLOAT_VALUE(y);
if (dx < 0 && dy != round(dy))
return rb_funcall(rb_complex_raw1(x), idPow, 1, y);
}
else {
return rb_num_coerce_bin(x, y, idPow);
}
return DBL2NUM(pow(dx, dy));
}
```
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)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
}
else {
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)
{
if (RB_TYPE_P(y, T_FIXNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
}
else {
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;

if (RB_TYPE_P(y, T_FIXNUM)) {
f_y = FIX2LONG(y);
return DBL2NUM(RFLOAT_VALUE(x) / (double)f_y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
d = rb_big2dbl(y);
return DBL2NUM(RFLOAT_VALUE(x) / d);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
return DBL2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '/');
}
}
```
float < real → true or false click to toggle source

Returns `true` if `float` is less than `real`.

The result of `NaN < NaN` is undefined, so the implementation-dependent value is returned.

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

a = RFLOAT_VALUE(x);
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return -FIX2INT(rel) < 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
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;
}
```
float <= real → true or false click to toggle source

Returns `true` if `float` is less than or equal to `real`.

The result of `NaN <= NaN` is undefined, so the implementation-dependent value is returned.

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

a = RFLOAT_VALUE(x);
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return -FIX2INT(rel) <= 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, idLE);
}
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(a)) return Qfalse;
#endif
return (a <= b)?Qtrue:Qfalse;
}
```
float <=> real → -1, 0, +1 or nil click to toggle source

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

The result of `NaN <=> NaN` is undefined, so the implementation-dependent value is returned.

`nil` is returned if the two values are incomparable.

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

a = RFLOAT_VALUE(x);
if (isnan(a)) return Qnil;
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return INT2FIX(-FIX2INT(rel));
return rel;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
}
else {
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, id_cmp);
}
return rb_dbl_cmp(a, b);
}
```
float == obj → true or false click to toggle source

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

The result of `NaN == NaN` is undefined, so the implementation-dependent value is returned.

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

if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
return rb_integer_float_eq(y, x);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
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;
}
```
float == obj → true or false click to toggle source

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

The result of `NaN == NaN` is undefined, so the implementation-dependent value is returned.

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

if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
return rb_integer_float_eq(y, x);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
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;
}
```
float > real → true or false click to toggle source

Returns `true` if `float` is greater than `real`.

The result of `NaN > NaN` is undefined, so the implementation-dependent value is returned.

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

a = RFLOAT_VALUE(x);
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return -FIX2INT(rel) > 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
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;
}
```
float >= real → true or false click to toggle source

Returns `true` if `float` is greater than or equal to `real`.

The result of `NaN >= NaN` is undefined, so the implementation-dependent value is returned.

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

a = RFLOAT_VALUE(x);
if (RB_TYPE_P(y, T_FIXNUM) || RB_TYPE_P(y, T_BIGNUM)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return -FIX2INT(rel) >= 0 ? Qtrue : Qfalse;
return Qfalse;
}
else if (RB_TYPE_P(y, T_FLOAT)) {
b = RFLOAT_VALUE(y);
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(b)) return Qfalse;
#endif
}
else {
return rb_num_coerce_relop(x, y, idGE);
}
#if defined(_MSC_VER) && _MSC_VER < 1300
if (isnan(a)) return Qfalse;
#endif
return (a >= b)?Qtrue:Qfalse;
}
```
abs → float click to toggle source

Returns the absolute value of `float`.

```(-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);
}
```
angle → 0 or float click to toggle source

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

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 `float`.

```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 a `numeric` and a `float` represented as Float objects.

This is achieved by converting a `numeric` 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.

```42.0.divmod 6 #=> [7, 0.0]
42.0.divmod 5 #=> [8, 2.0]
```
```
static VALUE
flo_divmod(VALUE x, VALUE y)
{
double fy, div, mod;
volatile VALUE a, b;

if (RB_TYPE_P(y, T_FIXNUM)) {
fy = (double)FIX2LONG(y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
fy = rb_big2dbl(y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
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?(obj) → true or false click to toggle source

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

The result of `NaN.eql?(NaN)` is undefined, so the implementation-dependent value is returned.

```1.0.eql?(1)   #=> false
```
```
static VALUE
flo_eql(VALUE x, VALUE y)
{
if (RB_TYPE_P(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;
}
```
fdiv(numeric) → float click to toggle source

Returns `float / numeric`, same as Float#/.

```
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 `float` 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);

#ifdef HAVE_ISFINITE
if (!isfinite(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 `float`.

```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)
{
return rb_dbl_hash(RFLOAT_VALUE(num));
}
```
infinite? → nil, -1, +1 click to toggle source

Return values corresponding to the value of `float`:

`finite`

`nil`

`-Infinity`

`-1`

+`Infinity`

`1`

For example:

```(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;
}
```
inspect() click to toggle source
Alias for: to_s
magnitude → float click to toggle source

Returns the absolute value of `float`.

```(-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);
}
```
modulo(other) → float click to toggle source

Return the modulo after division of `float` 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;

if (RB_TYPE_P(y, T_FIXNUM)) {
fy = (double)FIX2LONG(y);
}
else if (RB_TYPE_P(y, T_BIGNUM)) {
fy = rb_big2dbl(y);
}
else if (RB_TYPE_P(y, T_FLOAT)) {
fy = RFLOAT_VALUE(y);
}
else {
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 `float` 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;
}
```
negative? → true or false click to toggle source

Returns `true` if `float` is less than 0.

```
static VALUE
flo_negative_p(VALUE num)
{
double f = RFLOAT_VALUE(num);
return f < 0.0 ? Qtrue : Qfalse;
}
```
next_float → float click to toggle source

Returns the next representable floating-point number.

Float::MAX.next_float and Float::INFINITY.next_float is Float::INFINITY.

Float::NAN.next_float is Float::NAN.

For example:

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

p 0.01.next_float - 0.01   #=> 1.734723475976807e-18
p 1.0.next_float - 1.0     #=> 2.220446049250313e-16
p 100.0.next_float - 100.0 #=> 1.4210854715202004e-14

f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.next_float }
#=> 0x1.47ae147ae147bp-7 0.01
#   0x1.47ae147ae147cp-7 0.010000000000000002
#   0x1.47ae147ae147dp-7 0.010000000000000004
#   0x1.47ae147ae147ep-7 0.010000000000000005
#   0x1.47ae147ae147fp-7 0.010000000000000007
#   0x1.47ae147ae148p-7  0.010000000000000009
#   0x1.47ae147ae1481p-7 0.01000000000000001
#   0x1.47ae147ae1482p-7 0.010000000000000012
#   0x1.47ae147ae1483p-7 0.010000000000000014
#   0x1.47ae147ae1484p-7 0.010000000000000016
#   0x1.47ae147ae1485p-7 0.010000000000000018
#   0x1.47ae147ae1486p-7 0.01000000000000002
#   0x1.47ae147ae1487p-7 0.010000000000000021
#   0x1.47ae147ae1488p-7 0.010000000000000023
#   0x1.47ae147ae1489p-7 0.010000000000000024
#   0x1.47ae147ae148ap-7 0.010000000000000026
#   0x1.47ae147ae148bp-7 0.010000000000000028
#   0x1.47ae147ae148cp-7 0.01000000000000003
#   0x1.47ae147ae148dp-7 0.010000000000000031
#   0x1.47ae147ae148ep-7 0.010000000000000033

f = 0.0
100.times { f += 0.1 }
p f                            #=> 9.99999999999998       # should be 10.0 in the ideal world.
p 10-f                         #=> 1.9539925233402755e-14 # the floating-point error.
p(10.0.next_float-10)          #=> 1.7763568394002505e-15 # 1 ulp (units in the last place).
p((10-f)/(10.0.next_float-10)) #=> 11.0                   # the error is 11 ulp.
p((10-f)/(10*Float::EPSILON))  #=> 8.8                    # approximation of the above.
p "%a" % f                     #=> "0x1.3fffffffffff5p+3" # the last hex digit is 5.  16 - 5 = 11 ulp.
```
```
static VALUE
flo_next_float(VALUE vx)
{
double x, y;
x = NUM2DBL(vx);
y = nextafter(x, INFINITY);
return DBL2NUM(y);
}
```
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
```
```
static VALUE
float_numerator(VALUE self)
{
double d = RFLOAT_VALUE(self);
if (isinf(d) || isnan(d))
return self;
return rb_call_super(0, 0);
}
```
phase → 0 or float click to toggle source

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);
}
```
positive? → true or false click to toggle source

Returns `true` if `float` is greater than 0.

```
static VALUE
flo_positive_p(VALUE num)
{
double f = RFLOAT_VALUE(num);
return f > 0.0 ? Qtrue : Qfalse;
}
```
prev_float → float click to toggle source

Returns the previous representable floating-point number.

(-Float::MAX).prev_float and (-Float::INFINITY).prev_float is -Float::INFINITY.

Float::NAN.prev_float is Float::NAN.

For example:

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

p 0.01 - 0.01.prev_float   #=> 1.734723475976807e-18
p 1.0 - 1.0.prev_float     #=> 1.1102230246251565e-16
p 100.0 - 100.0.prev_float #=> 1.4210854715202004e-14

f = 0.01; 20.times { printf "%-20a %s\n", f, f.to_s; f = f.prev_float }
#=> 0x1.47ae147ae147bp-7 0.01
#   0x1.47ae147ae147ap-7 0.009999999999999998
#   0x1.47ae147ae1479p-7 0.009999999999999997
#   0x1.47ae147ae1478p-7 0.009999999999999995
#   0x1.47ae147ae1477p-7 0.009999999999999993
#   0x1.47ae147ae1476p-7 0.009999999999999992
#   0x1.47ae147ae1475p-7 0.00999999999999999
#   0x1.47ae147ae1474p-7 0.009999999999999988
#   0x1.47ae147ae1473p-7 0.009999999999999986
#   0x1.47ae147ae1472p-7 0.009999999999999985
#   0x1.47ae147ae1471p-7 0.009999999999999983
#   0x1.47ae147ae147p-7  0.009999999999999981
#   0x1.47ae147ae146fp-7 0.00999999999999998
#   0x1.47ae147ae146ep-7 0.009999999999999978
#   0x1.47ae147ae146dp-7 0.009999999999999976
#   0x1.47ae147ae146cp-7 0.009999999999999974
#   0x1.47ae147ae146bp-7 0.009999999999999972
#   0x1.47ae147ae146ap-7 0.00999999999999997
#   0x1.47ae147ae1469p-7 0.009999999999999969
#   0x1.47ae147ae1468p-7 0.009999999999999967
```
```
static VALUE
flo_prev_float(VALUE vx)
{
double x, y;
x = NUM2DBL(vx);
y = nextafter(x, -INFINITY);
return DBL2NUM(y);
}
```
quo(numeric) → float click to toggle source

Returns `float / numeric`, same as Float#/.

```
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 the optional 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 to_r.

```
static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
VALUE e;

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) {
return rb_flt_rationalize_with_prec(self, e);
}
else {
return rb_flt_rationalize(self);
}
}
```
round([ndigits]) → integer or float click to toggle source

Rounds `float` 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

Since `float` 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

Returns the `float` truncated to an Integer.

Synonyms are to_i, to_int, and truncate.

```
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_int → integer click to toggle source

Returns the `float` truncated to an Integer.

Synonyms are to_i, to_int, and truncate.

```
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.

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

See rationalize.

```
static VALUE
float_to_r(VALUE self)
{
VALUE f, n;

float_decode_internal(self, &f, &n);
{
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
#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 `float`, the call may return `NaN`, `Infinity`, and `-Infinity`.

```
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 + (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 <= 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 {
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 → integer click to toggle source

Returns the `float` truncated to an Integer.

Synonyms are to_i, to_int, and truncate.

```
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 `float` 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, code samples, 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.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.