Class: Float

Inherits:
Numeric show all
Defined in:
numeric.c,
numeric.c

Overview

******************************************************************

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:

- https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
- https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_imprecise
- https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Constant Summary collapse

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.
INT2FIX(FLT_RADIX)
MANT_DIG =

The number of base digits for the double data type.

Usually defaults to 53.

INT2FIX(DBL_MANT_DIG)
DIG =

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

Usually defaults to 15.

INT2FIX(DBL_DIG)
MIN_EXP =

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

Usually defaults to -1021.

INT2FIX(DBL_MIN_EXP)
MAX_EXP =

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

Usually defaults to 1024.

INT2FIX(DBL_MAX_EXP)
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.

INT2FIX(DBL_MIN_10_EXP)
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.

INT2FIX(DBL_MAX_10_EXP)
MIN =

:MIN. 0.0.next_float returns the smallest positive floating point number including denormalized numbers.

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
MAX =

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

Usually defaults to 1.7976931348623157e+308.

DBL2NUM(DBL_MAX)
EPSILON =

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

Usually defaults to 2.2204460492503131e-16.

DBL2NUM(DBL_EPSILON)
INFINITY =

An expression representing positive infinity.

DBL2NUM(HUGE_VAL)
NAN =

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

DBL2NUM(nan(""))

Instance Method Summary collapse

Methods inherited from Numeric

#[email protected], #abs2, #clone, #conj, #conjugate, #div, #dup, #i, #imag, #imaginary, #integer?, #nonzero?, #polar, #real, #real?, #rect, #rectangular, #remainder, #singleton_method_added, #step, #to_c

Methods included from Comparable

#between?, #clamp

Instance Method Details

#%(other) ⇒ Float #modulo(other) ⇒ Float

Returns the modulo after division of float by other.

6543.21.modulo(137)      #=> 104.21000000000004
6543.21.modulo(137.24)   #=> 92.92999999999961

Overloads:


1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
# File 'numeric.c', line 1255

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));
}

#*(other) ⇒ Float

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

Returns:


1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
# File 'numeric.c', line 1101

VALUE
rb_float_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, '*');
    }
}

#**(other) ⇒ Float

Raises float to the power of other.

2.0**3   #=> 8.0

Returns:


1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
# File 'numeric.c', line 1327

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 (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_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
    }
    else {
	return rb_num_coerce_bin(x, y, idPow);
    }
    return DBL2NUM(pow(dx, dy));
}

#+(other) ⇒ Float

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

Returns:


1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
# File 'numeric.c', line 1053

VALUE
rb_float_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, '+');
    }
}

#-(other) ⇒ Float

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

Returns:


1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
# File 'numeric.c', line 1077

VALUE
rb_float_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

Returns float, negated.

Returns:


1040
1041
1042
1043
1044
# File 'numeric.c', line 1040

VALUE
rb_float_uminus(VALUE flt)
{
    return DBL2NUM(-RFLOAT_VALUE(flt));
}

#/(other) ⇒ Float

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

Returns:


1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
# File 'numeric.c', line 1155

VALUE
rb_float_div(VALUE x, VALUE y)
{
    double num = RFLOAT_VALUE(x);
    double den;
    double ret;

    if (RB_TYPE_P(y, T_FIXNUM)) {
        den = FIX2LONG(y);
    }
    else if (RB_TYPE_P(y, T_BIGNUM)) {
        den = rb_big2dbl(y);
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
        den = RFLOAT_VALUE(y);
    }
    else {
	return rb_num_coerce_bin(x, y, '/');
    }

    ret = double_div_double(num, den);
    return DBL2NUM(ret);
}

#<(real) ⇒ Boolean

Returns true if float is less than real.

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

Returns:

  • (Boolean)

1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
# File 'numeric.c', line 1610

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 -FIX2LONG(rel) < 0 ? Qtrue : Qfalse;
        return Qfalse;
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
	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 (a < b)?Qtrue:Qfalse;
}

#<=(real) ⇒ Boolean

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

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

Returns:

  • (Boolean)

1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
# File 'numeric.c', line 1647

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 -FIX2LONG(rel) <= 0 ? Qtrue : Qfalse;
        return Qfalse;
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
	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 (a <= b)?Qtrue:Qfalse;
}

#<=>(real) ⇒ -1, ...

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

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

nil is returned if the two values are incomparable.

Returns:

  • (-1, 0, +1, nil)

1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
# File 'numeric.c', line 1488

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 LONG2FIX(-FIX2LONG(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);
}

#==Object

#===Object

#>(real) ⇒ Boolean

Returns true if float is greater than real.

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

Returns:

  • (Boolean)

1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
# File 'numeric.c', line 1536

VALUE
rb_float_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 -FIX2LONG(rel) > 0 ? Qtrue : Qfalse;
        return Qfalse;
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
	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 (a > b)?Qtrue:Qfalse;
}

#>=(real) ⇒ Boolean

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

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

Returns:

  • (Boolean)

1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
# File 'numeric.c', line 1573

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 -FIX2LONG(rel) >= 0 ? Qtrue : Qfalse;
        return Qfalse;
    }
    else if (RB_TYPE_P(y, T_FLOAT)) {
	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 (a >= b)?Qtrue:Qfalse;
}

#absFloat #magnitudeFloat

Returns the absolute value of float.

(-34.56).abs   #=> 34.56
-34.56.abs     #=> 34.56
34.56.abs      #=> 34.56

Float#magnitude is an alias for Float#abs.

Overloads:


1731
1732
1733
1734
1735
1736
# File 'numeric.c', line 1731

VALUE
rb_float_abs(VALUE flt)
{
    double val = fabs(RFLOAT_VALUE(flt));
    return DBL2NUM(val);
}

#arg0, Float #angle0, Float #phase0, Float

Returns 0 if the value is positive, pi otherwise.

Overloads:


2278
2279
2280
2281
2282
2283
2284
2285
2286
# File 'complex.c', line 2278

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);
}

#arg0, Float #angle0, Float #phase0, Float

Returns 0 if the value is positive, pi otherwise.

Overloads:


2278
2279
2280
2281
2282
2283
2284
2285
2286
# File 'complex.c', line 2278

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([ndigits]) ⇒ Integer, Float

Returns the smallest number greater than or equal to float with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns a floating point number when ndigits is positive, otherwise returns an integer.

1.2.ceil      #=> 2
2.0.ceil      #=> 2
(-1.2).ceil   #=> -1
(-2.0).ceil   #=> -2

1.234567.ceil(2)   #=> 1.24
1.234567.ceil(3)   #=> 1.235
1.234567.ceil(4)   #=> 1.2346
1.234567.ceil(5)   #=> 1.23457

34567.89.ceil(-5)  #=> 100000
34567.89.ceil(-4)  #=> 40000
34567.89.ceil(-3)  #=> 35000
34567.89.ceil(-2)  #=> 34600
34567.89.ceil(-1)  #=> 34570
34567.89.ceil(0)   #=> 34568
34567.89.ceil(1)   #=> 34567.9
34567.89.ceil(2)   #=> 34567.89
34567.89.ceil(3)   #=> 34567.89

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

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

Returns:


2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
# File 'numeric.c', line 2047

static VALUE
flo_ceil(int argc, VALUE *argv, VALUE num)
{
    int ndigits = 0;

    if (rb_check_arity(argc, 0, 1)) {
	ndigits = NUM2INT(argv[0]);
    }
    return rb_float_ceil(num, ndigits);
}

#coerce(numeric) ⇒ Array

Returns an array with both numeric and float represented as Float objects.

This is achieved by converting numeric to a Float.

1.2.coerce(3)       #=> [3.0, 1.2]
2.5.coerce(1.1)     #=> [1.1, 2.5]

Returns:


1027
1028
1029
1030
1031
# File 'numeric.c', line 1027

static VALUE
flo_coerce(VALUE x, VALUE y)
{
    return rb_assoc_new(rb_Float(y), x);
}

#denominatorInteger

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

See also Float#numerator.

Returns:


2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
# File 'rational.c', line 2111

VALUE
rb_float_denominator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE r;
    if (isinf(d) || isnan(d))
	return INT2FIX(1);
    r = float_to_r(self);
    return nurat_denominator(r);
}

#divmod(numeric) ⇒ Array

See Numeric#divmod.

42.0.divmod(6)   #=> [7, 0.0]
42.0.divmod(5)   #=> [8, 2.0]

Returns:


1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
# File 'numeric.c', line 1294

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?Boolean

Returns:

  • (Boolean)

#fdiv(numeric) ⇒ Float #quo(numeric) ⇒ Float

Returns float / numeric, same as Float#/.

Overloads:


1187
1188
1189
1190
1191
# File 'numeric.c', line 1187

static VALUE
flo_quo(VALUE x, VALUE y)
{
    return num_funcall1(x, '/', y);
}

#finite?Boolean

Returns true if float is a valid IEEE floating point number, i.e. it is not infinite and Float#nan? is false.

Returns:

  • (Boolean)

1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
# File 'numeric.c', line 1803

VALUE
rb_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([ndigits]) ⇒ Integer, Float

Returns the largest number less than or equal to float with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns a floating point number when ndigits is positive, otherwise returns an integer.

1.2.floor      #=> 1
2.0.floor      #=> 2
(-1.2).floor   #=> -2
(-2.0).floor   #=> -2

1.234567.floor(2)   #=> 1.23
1.234567.floor(3)   #=> 1.234
1.234567.floor(4)   #=> 1.2345
1.234567.floor(5)   #=> 1.23456

34567.89.floor(-5)  #=> 0
34567.89.floor(-4)  #=> 30000
34567.89.floor(-3)  #=> 34000
34567.89.floor(-2)  #=> 34500
34567.89.floor(-1)  #=> 34560
34567.89.floor(0)   #=> 34567
34567.89.floor(1)   #=> 34567.8
34567.89.floor(2)   #=> 34567.89
34567.89.floor(3)   #=> 34567.89

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

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

Returns:


1998
1999
2000
2001
2002
2003
2004
2005
2006
# File 'numeric.c', line 1998

static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
    int ndigits = 0;
    if (rb_check_arity(argc, 0, 1)) {
	ndigits = NUM2INT(argv[0]);
    }
    return rb_float_floor(num, ndigits);
}

#hashInteger

Returns a hash code for this float.

See also Object#hash.

Returns:


1452
1453
1454
1455
1456
# File 'numeric.c', line 1452

static VALUE
flo_hash(VALUE num)
{
    return rb_dbl_hash(RFLOAT_VALUE(num));
}

#infinite?-1, ...

Returns nil, -1, or 1 depending on whether the value is finite, -Infinity, or +Infinity.

(0.0).infinite?        #=> nil
(-1.0/0.0).infinite?   #=> -1
(+1.0/0.0).infinite?   #=> 1

Returns:

  • (-1, 1, nil)

1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
# File 'numeric.c', line 1783

VALUE
rb_flo_is_infinite_p(VALUE num)
{
    double value = RFLOAT_VALUE(num);

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

    return Qnil;
}

#absFloat #magnitudeFloat

Returns the absolute value of float.

(-34.56).abs   #=> 34.56
-34.56.abs     #=> 34.56
34.56.abs      #=> 34.56

Float#magnitude is an alias for Float#abs.

Overloads:


1731
1732
1733
1734
1735
1736
# File 'numeric.c', line 1731

VALUE
rb_float_abs(VALUE flt)
{
    double val = fabs(RFLOAT_VALUE(flt));
    return DBL2NUM(val);
}

#%(other) ⇒ Float #modulo(other) ⇒ Float

Returns the modulo after division of float by other.

6543.21.modulo(137)      #=> 104.21000000000004
6543.21.modulo(137.24)   #=> 92.92999999999961

Overloads:


1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
# File 'numeric.c', line 1255

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?Boolean

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

Returns:

  • (Boolean)

1763
1764
1765
1766
1767
1768
1769
# File 'numeric.c', line 1763

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

    return isnan(value) ? Qtrue : Qfalse;
}

#negative?Boolean

Returns true if float is less than 0.

Returns:

  • (Boolean)

2461
2462
2463
2464
2465
2466
# File 'numeric.c', line 2461

static VALUE
flo_negative_p(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    return f < 0.0 ? Qtrue : Qfalse;
}

#next_floatFloat

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:

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

0.01.next_float - 0.01     #=> 1.734723475976807e-18
1.0.next_float - 1.0       #=> 2.220446049250313e-16
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 }
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.

Returns:


1880
1881
1882
1883
1884
# File 'numeric.c', line 1880

static VALUE
flo_next_float(VALUE vx)
{
    return flo_nextafter(vx, HUGE_VAL);
}

#numeratorInteger

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.

Returns:


2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
# File 'rational.c', line 2091

VALUE
rb_float_numerator(VALUE self)
{
    double d = RFLOAT_VALUE(self);
    VALUE r;
    if (isinf(d) || isnan(d))
	return self;
    r = float_to_r(self);
    return nurat_numerator(r);
}

#arg0, Float #angle0, Float #phase0, Float

Returns 0 if the value is positive, pi otherwise.

Overloads:


2278
2279
2280
2281
2282
2283
2284
2285
2286
# File 'complex.c', line 2278

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?Boolean

Returns true if float is greater than 0.

Returns:

  • (Boolean)

2447
2448
2449
2450
2451
2452
# File 'numeric.c', line 2447

static VALUE
flo_positive_p(VALUE num)
{
    double f = RFLOAT_VALUE(num);
    return f > 0.0 ? Qtrue : Qfalse;
}

#prev_floatFloat

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:

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

0.01 - 0.01.prev_float     #=> 1.734723475976807e-18
1.0 - 1.0.prev_float       #=> 1.1102230246251565e-16
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

Returns:


1928
1929
1930
1931
1932
# File 'numeric.c', line 1928

static VALUE
flo_prev_float(VALUE vx)
{
    return flo_nextafter(vx, -HUGE_VAL);
}

#fdiv(numeric) ⇒ Float #quo(numeric) ⇒ Float

Returns float / numeric, same as Float#/.

Overloads:


1187
1188
1189
1190
1191
# File 'numeric.c', line 1187

static VALUE
flo_quo(VALUE x, VALUE y)
{
    return num_funcall1(x, '/', y);
}

#rationalize([eps]) ⇒ Object

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.


2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
# File 'rational.c', line 2293

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][, half: mode]) ⇒ Integer, Float

Returns float rounded to the nearest value with a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns a floating point number when ndigits is positive, otherwise returns an integer.

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

If the optional half keyword argument is given, numbers that are half-way between two possible rounded values will be rounded according to the specified tie-breaking mode:

  • :up or nil: round half away from zero (default)

  • :down: round half toward zero

  • :even: round half toward the nearest even number

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

Returns:


2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
# File 'numeric.c', line 2307

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);
	f = pow(10, ndigits);
	x = ROUND_CALL(mode, round, (number, f));
	return DBL2NUM(x / f);
    }
    return num;
}

#to_fself

Since float is already a Float, returns self.

Returns:

  • (self)

1711
1712
1713
1714
1715
# File 'numeric.c', line 1711

static VALUE
flo_to_f(VALUE num)
{
    return num;
}

#to_iInteger #to_intInteger

Returns the float truncated to an Integer.

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

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

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

#to_int is an alias for #to_i.

Overloads:


2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
# File 'numeric.c', line 2397

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);
}

#to_iInteger #to_intInteger

Returns the float truncated to an Integer.

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

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

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

#to_int is an alias for #to_i.

Overloads:


2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
# File 'numeric.c', line 2397

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);
}

#to_rObject

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.


2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
# File 'rational.c', line 2208

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_sString Also known as: inspect

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.

Returns:


940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
# File 'numeric.c', line 940

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)) {
	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);
    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 {
        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;
}

#truncate([ndigits]) ⇒ Integer, Float

Returns float truncated (toward zero) to a precision of ndigits decimal digits (default: 0).

When the precision is negative, the returned value is an integer with at least ndigits.abs trailing zeros.

Returns a floating point number when ndigits is positive, otherwise returns an integer.

2.8.truncate           #=> 2
(-2.8).truncate        #=> -2
1.234567.truncate(2)   #=> 1.23
34567.89.truncate(-2)  #=> 34500

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

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

Returns:


2431
2432
2433
2434
2435
2436
2437
2438
# File 'numeric.c', line 2431

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?Boolean

Returns true if float is 0.0.

Returns:

  • (Boolean)

1745
1746
1747
1748
1749
# File 'numeric.c', line 1745

static VALUE
flo_zero_p(VALUE num)
{
    return flo_iszero(num) ? Qtrue : Qfalse;
}