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:

- http://docs.sun.com/source/806-3568/ncg_goldberg.html
- https://github.com/rdp/ruby_tutorials_core/wiki/Ruby-Talk-FAQ#floats_imprecise
- http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Constant Summary collapse

ROUNDS =

-1:: Indeterminable 0:: Rounding towards zero 1:: Rounding to the nearest number 2:: Rounding towards positive infinity 3:: Rounding towards negative infinity

Deprecated, do not use.

Represents the rounding mode for floating point addition at the start time.

Usually defaults to 1, rounding to the nearest number.

Other modes include
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:


1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
# File 'numeric.c', line 1239

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:


1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
# File 'numeric.c', line 1085

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:


1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
# File 'numeric.c', line 1311

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


1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
# File 'numeric.c', line 1037

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:


1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
# File 'numeric.c', line 1061

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

Returns float, negated.

Returns:


1024
1025
1026
1027
1028
# File 'numeric.c', line 1024

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:


1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
# File 'numeric.c', line 1139

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)

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
# File 'numeric.c', line 1590

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)

1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
# File 'numeric.c', line 1627

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)

1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
# File 'numeric.c', line 1468

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)

1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
# File 'numeric.c', line 1516

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)

1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
# File 'numeric.c', line 1553

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:


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

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:


2273
2274
2275
2276
2277
2278
2279
2280
2281
# File 'complex.c', line 2273

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:


2273
2274
2275
2276
2277
2278
2279
2280
2281
# File 'complex.c', line 2273

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:


2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
# File 'numeric.c', line 2019

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:


1011
1012
1013
1014
1015
# File 'numeric.c', line 1011

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:


2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
# File 'rational.c', line 2112

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);
    if (canonicalization && k_integer_p(r)) {
	return ONE;
    }
    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:


1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
# File 'numeric.c', line 1278

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:


1171
1172
1173
1174
1175
# File 'numeric.c', line 1171

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)

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

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:


1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
# File 'numeric.c', line 1950

static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
    double number, f;
    int ndigits = 0;

    if (rb_check_arity(argc, 0, 1)) {
	ndigits = NUM2INT(argv[0]);
    }
    number = RFLOAT_VALUE(num);
    if (number == 0.0) {
	return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
    }
    if (ndigits > 0) {
	int binexp;
	frexp(number, &binexp);
	if (float_round_overflow(ndigits, binexp)) return num;
	if (number > 0.0 && float_round_underflow(ndigits, binexp))
	    return DBL2NUM(0.0);
	f = pow(10, ndigits);
	f = floor(number * f) / f;
	return DBL2NUM(f);
    }
    else {
	num = dbl2ival(floor(number));
	if (ndigits < 0) num = rb_int_floor(num, ndigits);
	return num;
    }
}

#hashInteger

Returns a hash code for this float.

See also Object#hash.

Returns:


1432
1433
1434
1435
1436
# File 'numeric.c', line 1432

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)

1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
# File 'numeric.c', line 1763

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:


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

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:


1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
# File 'numeric.c', line 1239

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)

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

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)

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

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:


1851
1852
1853
1854
1855
1856
1857
1858
# File 'numeric.c', line 1851

static VALUE
flo_next_float(VALUE vx)
{
    double x, y;
    x = NUM2DBL(vx);
    y = nextafter(x, HUGE_VAL);
    return DBL2NUM(y);
}

#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:


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

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);
    if (canonicalization && k_integer_p(r)) {
	return r;
    }
    return nurat_numerator(r);
}

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

Returns 0 if the value is positive, pi otherwise.

Overloads:


2273
2274
2275
2276
2277
2278
2279
2280
2281
# File 'complex.c', line 2273

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)

2419
2420
2421
2422
2423
2424
# File 'numeric.c', line 2419

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:


1902
1903
1904
1905
1906
1907
1908
1909
# File 'numeric.c', line 1902

static VALUE
flo_prev_float(VALUE vx)
{
    double x, y;
    x = NUM2DBL(vx);
    y = nextafter(x, -HUGE_VAL);
    return DBL2NUM(y);
}

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

Returns float / numeric, same as Float#/.

Overloads:


1171
1172
1173
1174
1175
# File 'numeric.c', line 1171

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.


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

static VALUE
float_rationalize(int argc, VALUE *argv, VALUE self)
{
    double d = RFLOAT_VALUE(self);

    if (d < 0.0)
        return rb_rational_uminus(float_rationalize(argc, argv, DBL2NUM(-d)));

    if (rb_check_arity(argc, 0, 1)) {
        return rb_flt_rationalize_with_prec(self, argv[0]);
    }
    else {
        return rb_flt_rationalize(self);
    }
}

#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:


2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
# File 'numeric.c', line 2279

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)

1691
1692
1693
1694
1695
# File 'numeric.c', line 1691

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:


2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
# File 'numeric.c', line 2369

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:


2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
# File 'numeric.c', line 2369

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.


2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
# File 'rational.c', line 2212

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:


927
928
929
930
931
932
933
934
935
936
937
938
939
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
# File 'numeric.c', line 927

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 {
      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:


2403
2404
2405
2406
2407
2408
2409
2410
# File 'numeric.c', line 2403

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)

1725
1726
1727
1728
1729
# File 'numeric.c', line 1725

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