class Float
Practical examples and pitfalls for Float
Float examples: compare measurements and handle non-finite values
Practical notes by Ruby-Doc.org
Compare with a meaningful tolerance
A calculated value and an expected value can differ slightly in their binary floating-point representations. There is no way to store every decimal fraction exactly in a binary float. The first example illustrates that difference, then compares the values using a small absolute tolerance.
actual = 0.1 + 0.2
p actual == 0.3
p (actual - 0.3).abs < 1e-12
false true
This tolerance choice isn't meant to be used across your application. The leeway allowed for a distance or temperature reading depends on the units, scale and significance of the measurement. Determine which tolerance rule best fits the context and size of your data; don't hide that determination by rounding both sides of a calculation to the appropriate number of decimal places and then comparing their string representations.
Decide how to handle non-finite values
An expression can also produce infinity or NaN (not a number). Use nan? to recognize NaN; equality with itself does not do that job. Those are floating-point values as well, so simply checking whether the object belongs to a certain class won't exclude those either. finite? clearly expresses your question if an output must be an ordinary finite measurement.
values = [1.5, Float::INFINITY, Float::NAN]
p values.map(&:finite?)
p Float::NAN.nan?
p Float::NAN == Float::NAN
[true, false, false] true false
If a calculated output produces infinity or NaN, do not silently replace that with zero in a report. Zero may actually be a valid measurement. Do not confuse a measured zero with missing input or an expression that couldn't possibly produce a finite result. The interface can then explain which case occurred, rather than presenting a fabricated measurement.
Don't put exact quantities into an approximate representation
Integers are the natural home for counts. For exact fractional arithmetic, consider rational numbers. For decimal arithmetic, consider a decimal library such as BigDecimal. Converting a decimal string to float prior to converting it to another type could have lost information before the second conversion even occurs.
When testing a new numerical helper, test zero, values near the comparison boundary and any non-finite quantities that callers might pass to it. Give these cases separate expected results. A properly formatted number does not guarantee that the original calculations were performed within some acceptable bounds of accuracy.
API reference: Float API reference
A Float object stores a real number using the native architecture’s double-precision floating-point representation.
Float Imprecisions
Some real numbers can be represented precisely as Float objects:
37.5 # => 37.5 98.75 # => 98.75 12.3125 # => 12.3125
Others cannot; among these are the transcendental numbers, including:
-
Pi, π: in mathematics, a number of infinite precision: 3.1415926535897932384626433… (to 25 places); in Ruby, it is of limited precision (in this case, to 16 decimal places):
Math::PI # => 3.141592653589793
-
Euler’s number, e: in mathematics, a number of infinite precision: 2.7182818284590452353602874… (to 25 places); in Ruby, it is of limited precision (in this case, to 15 decimal places):
Math::E # => 2.718281828459045
Some floating-point computations in Ruby give precise results:
1.0/2 # => 0.5 100.0/8 # => 12.5
Others do not:
-
In mathematics, 2/3 as a decimal number is an infinitely-repeating decimal: 0.666… (forever); in Ruby,
2.0/3is of limited precision (in this case, to 16 decimal places):2.0/3 # => 0.6666666666666666
-
In mathematics, the square root of 2 is an irrational number of infinite precision: 1.4142135623730950488016887… (to 25 decimal places); in Ruby, it is of limited precision (in this case, to 16 decimal places):
Math.sqrt(2.0) # => 1.4142135623730951
-
Even a simple computation can introduce imprecision:
x = 0.1 + 0.2 # => 0.30000000000000004 y = 0.3 # => 0.3 x == y # => false
See:
Note that precise storage and computation of rational numbers is possible using Rational objects.
Creating a Float
You can create a Float object explicitly with:
You can convert certain objects to Floats with:
-
Method
Float.
What’s Here
First, what’s elsewhere. Class Float:
-
Inherits from class Numeric and class Object.
-
Includes module Comparable.
Here, class Float provides methods for:
Querying
-
finite?: Returns whetherselfis finite. -
hash: Returns the integer hash code forself. -
infinite?: Returns whetherselfis infinite. -
nan?: Returns whetherselfis a NaN (not-a-number).
Comparing
-
<: Returns whetherselfis less than the given value. -
<=: Returns whetherselfis less than or equal to the given value. -
<=>: Returns a number indicating whetherselfis less than, equal to, or greater than the given value. -
==(aliased as===andeql?): Returns whetherselfis equal to the given value. -
>: Returns whetherselfis greater than the given value. -
>=: Returns whetherselfis greater than or equal to the given value.
Converting
-
*: Returns the product ofselfand the given value. -
**: Returns the value ofselfraised to the power of the given value. -
+: Returns the sum ofselfand the given value. -
-: Returns the difference ofselfand the given value. -
/: Returns the quotient ofselfand the given value. -
ceil: Returns the smallest number greater than or equal toself. -
coerce: Returns a 2-element array containing the given value converted to a Float andself -
divmod: Returns a 2-element array containing the quotient and remainder results of dividingselfby the given value. -
fdiv: Returns the Float result of dividingselfby the given value. -
floor: Returns the greatest number smaller than or equal toself. -
next_float: Returns the next-larger representable Float. -
prev_float: Returns the next-smaller representable Float. -
quo: Returns the quotient from dividingselfby the given value. -
round: Returnsselfrounded to the nearest value, to a given precision. -
to_i(aliased asto_int): Returnsselftruncated to anInteger. -
to_s(aliased asinspect): Returns a string containing the place-value representation ofselfin the given radix. -
truncate: Returnsselftruncated to a given precision.
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
doubledata 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_floatreturns the smallest positive floating point number including denormalized numbers. - MIN_10_EXP
-
The smallest negative exponent in a double-precision floating point where 10 raised to this power minus 1.
Usually defaults to -307.
- MIN_EXP
-
The smallest possible exponent value in a double-precision floating point.
Usually defaults to -1021.
- NAN
-
An expression representing a value which is “not a number”.
- RADIX
-
The base of the floating point, or number of unique digits used to represent the number.
Usually defaults to 2 on most systems, which would represent a base-10 decimal.
Public Instance Methods
Source
static VALUE
flo_mod(VALUE x, VALUE y)
{
double fy;
if (FIXNUM_P(y)) {
fy = (double)FIX2LONG(y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
fy = rb_big2dbl(y);
}
else if (RB_FLOAT_TYPE_P(y)) {
fy = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_bin(x, y, '%');
}
return DBL2NUM(ruby_float_mod(RFLOAT_VALUE(x), fy));
}
Returns self modulo other as a Float.
For float f and real number r, these expressions are equivalent:
f % r f-r*(f/r).floor f.divmod(r)[1]
See Numeric#divmod.
Examples:
10.0 % 2 # => 0.0 10.0 % 3 # => 1.0 10.0 % 4 # => 2.0 10.0 % -2 # => 0.0 10.0 % -3 # => -2.0 10.0 % -4 # => -2.0 10.0 % 4.0 # => 2.0 10.0 % Rational(4, 1) # => 2.0
Source
VALUE
rb_float_mul(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y));
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '*');
}
}
Returns the numeric product of self and other:
f = 3.14 f * 2 # => 6.28 f * 2.0 # => 6.28 f * Rational(1, 2) # => 1.57 f * Complex(2, 0) # => (6.28+0.0i)
Source
VALUE
rb_float_pow(VALUE x, VALUE y)
{
double dx, dy;
if (y == INT2FIX(2)) {
dx = RFLOAT_VALUE(x);
return DBL2NUM(dx * dx);
}
else if (FIXNUM_P(y)) {
dx = RFLOAT_VALUE(x);
dy = (double)FIX2LONG(y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
dx = RFLOAT_VALUE(x);
dy = rb_big2dbl(y);
}
else if (RB_FLOAT_TYPE_P(y)) {
dx = RFLOAT_VALUE(x);
dy = RFLOAT_VALUE(y);
if (dx < 0 && dy != round(dy))
return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy);
}
else {
return rb_num_coerce_bin(x, y, idPow);
}
return DBL2NUM(pow(dx, dy));
}
Returns self raised to the power exponent:
f = 3.14 f ** 2 # => 9.8596 f ** -2 # => 0.1014239928597509 f ** 2.1 # => 11.054834900588839 f ** Rational(2, 1) # => 9.8596 f ** Complex(2, 0) # => (9.8596+0i)
Source
VALUE
rb_float_plus(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y));
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '+');
}
}
Returns the sum of self and other; the result may be inexact (see Float):
3.14 + 0 # => 3.14 3.14 + 1 # => 4.140000000000001 -3.14 + 0 # => -3.14 -3.14 + 1 # => -2.14 3.14 + -3.14 # => 0.0 -3.14 + -3.14 # => -6.28 3.14 + Complex(1, 0) # => (4.140000000000001+0i) 3.14 + Rational(1, 1) # => 4.140000000000001
Source
VALUE
rb_float_minus(VALUE x, VALUE y)
{
if (FIXNUM_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y));
}
else if (RB_BIGNUM_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y));
}
else if (RB_FLOAT_TYPE_P(y)) {
return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
}
else {
return rb_num_coerce_bin(x, y, '-');
}
}
Returns the difference of self and other:
f = 3.14 f - 1 # => 2.14 f - 1.0 # => 2.14 f - Rational(1, 1) # => 2.14 f - Complex(1, 0) # => (2.14+0i)
Source
# File numeric.rb, line 389 def -@ Primitive.attr! :leaf Primitive.cexpr! 'rb_float_uminus(self)' end
Returns self, negated:
-3.14 # => -3.14 -(-3.14) # => 3.14 -0.0 # => -0.0
Source
VALUE
rb_float_div(VALUE x, VALUE y)
{
double num = RFLOAT_VALUE(x);
double den;
double ret;
if (FIXNUM_P(y)) {
den = FIX2LONG(y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
den = rb_big2dbl(y);
}
else if (RB_FLOAT_TYPE_P(y)) {
den = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_bin(x, y, '/');
}
ret = double_div_double(num, den);
return DBL2NUM(ret);
}
Returns the quotient of self and other:
f = 3.14 f / 2 # => 1.57 f / 2.0 # => 1.57 f / Rational(2, 1) # => 1.57 f / Complex(2, 0) # => (1.57+0.0i)
Source
static VALUE
flo_lt(VALUE x, VALUE y)
{
double a, b;
a = RFLOAT_VALUE(x);
if (RB_INTEGER_TYPE_P(y)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return RBOOL(-FIX2LONG(rel) < 0);
return Qfalse;
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_relop(x, y, '<');
}
return RBOOL(a < b);
}
Returns whether the value of self is less than the value of other; other must be numeric, but may not be Complex:
2.0 < 3 # => true 2.0 < 3.0 # => true 2.0 < Rational(3, 1) # => true 2.0 < 2.0 # => false
Float::NAN < Float::NAN returns an implementation-dependent value.
Source
static VALUE
flo_le(VALUE x, VALUE y)
{
double a, b;
a = RFLOAT_VALUE(x);
if (RB_INTEGER_TYPE_P(y)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return RBOOL(-FIX2LONG(rel) <= 0);
return Qfalse;
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_relop(x, y, idLE);
}
return RBOOL(a <= b);
}
Returns whether the value of self is less than or equal to the value of other; other must be numeric, but may not be Complex:
2.0 <= 3 # => true 2.0 <= 3.0 # => true 2.0 <= Rational(3, 1) # => true 2.0 <= 2.0 # => true 2.0 <= 1.0 # => false
Float::NAN <= Float::NAN returns an implementation-dependent value.
Source
static VALUE
flo_cmp(VALUE x, VALUE y)
{
double a, b;
VALUE i;
a = RFLOAT_VALUE(x);
if (isnan(a)) return Qnil;
if (RB_INTEGER_TYPE_P(y)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return LONG2FIX(-FIX2LONG(rel));
return rel;
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
if (isinf(a) && !UNDEF_P(i = rb_check_funcall(y, rb_intern("infinite?"), 0, 0))) {
if (RTEST(i)) {
int j = rb_cmpint(i, x, y);
j = (a > 0.0) ? (j > 0 ? 0 : +1) : (j < 0 ? 0 : -1);
return INT2FIX(j);
}
if (a > 0.0) return INT2FIX(1);
return INT2FIX(-1);
}
return rb_num_coerce_cmp(x, y, id_cmp);
}
return rb_dbl_cmp(a, b);
}
Compares self and other.
Returns:
-
-1, ifselfis less thanother. -
0, ifselfis equal toother. -
1, ifselfis greater thanother. -
nil, if the two values are incommensurate.
Examples:
2.0 <=> 2.1 # => -1 2.0 <=> 2 # => 0 2.0 <=> 2.0 # => 0 2.0 <=> Rational(2, 1) # => 0 2.0 <=> Complex(2, 0) # => 0 2.0 <=> 1.9 # => 1 2.0 <=> 'foo' # => nil
Float::NAN <=> Float::NAN returns an implementation-dependent value.
Class Float includes module Comparable, each of whose methods uses Float#<=> for comparison.
Source
VALUE
rb_float_equal(VALUE x, VALUE y)
{
volatile double a, b;
if (RB_INTEGER_TYPE_P(y)) {
return rb_integer_float_eq(y, x);
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
return num_equal(x, y);
}
a = RFLOAT_VALUE(x);
return RBOOL(a == b);
}
Returns true if other has the same value as self, false otherwise:
2.0 == 2 # => true 2.0 == 2.0 # => true 2.0 == Rational(2, 1) # => true 2.0 == Complex(2, 0) # => true
Float::NAN == Float::NAN returns an implementation-dependent value.
Related: Float#eql? (requires other to be a Float).
Source
VALUE
rb_float_gt(VALUE x, VALUE y)
{
double a, b;
a = RFLOAT_VALUE(x);
if (RB_INTEGER_TYPE_P(y)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return RBOOL(-FIX2LONG(rel) > 0);
return Qfalse;
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_relop(x, y, '>');
}
return RBOOL(a > b);
}
Returns true if self is numerically greater than other:
2.0 > 1 # => true 2.0 > 1.0 # => true 2.0 > Rational(1, 2) # => true 2.0 > 2.0 # => false
Float::NAN > Float::NAN returns an implementation-dependent value.
Source
static VALUE
flo_ge(VALUE x, VALUE y)
{
double a, b;
a = RFLOAT_VALUE(x);
if (RB_TYPE_P(y, T_FIXNUM) || RB_BIGNUM_TYPE_P(y)) {
VALUE rel = rb_integer_float_cmp(y, x);
if (FIXNUM_P(rel))
return RBOOL(-FIX2LONG(rel) >= 0);
return Qfalse;
}
else if (RB_FLOAT_TYPE_P(y)) {
b = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_relop(x, y, idGE);
}
return RBOOL(a >= b);
}
Returns true if self is numerically greater than or equal to other:
2.0 >= 1 # => true 2.0 >= 1.0 # => true 2.0 >= Rational(1, 2) # => true 2.0 >= 2.0 # => true 2.0 >= 2.1 # => false
Float::NAN >= Float::NAN returns an implementation-dependent value.
Source
# File numeric.rb, line 373 def abs Primitive.attr! :leaf Primitive.cexpr! 'rb_float_abs(self)' end
Returns the absolute value of self:
(-34.56).abs # => 34.56 -34.56.abs # => 34.56 34.56.abs # => 34.56
Source
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);
}
Returns 0 if self is positive, Math::PI otherwise.
Source
static VALUE
flo_ceil(int argc, VALUE *argv, VALUE num)
{
int ndigits = flo_ndigits(argc, argv);
return rb_float_ceil(num, ndigits);
}
Returns a numeric that is a “ceiling” value for self, as specified by the given ndigits, which must be an integer-convertible object.
When ndigits is positive, returns a Float with ndigits decimal digits after the decimal point (as available, but no fewer than 1):
f = 12345.6789 f.ceil(1) # => 12345.7 f.ceil(3) # => 12345.679 f.ceil(30) # => 12345.6789 f = -12345.6789 f.ceil(1) # => -12345.6 f.ceil(3) # => -12345.678 f.ceil(30) # => -12345.6789 f = 0.0 f.ceil(1) # => 0.0 f.ceil(100) # => 0.0
When ndigits is non-positive, returns an Integer based on a computed granularity:
-
The granularity is
10 ** ndigits.abs. -
The returned value is the largest multiple of the granularity that is less than or equal to
self.
Examples with positive self:
| ndigits | Granularity | 12345.6789.ceil(ndigits) |
|---|---|---|
| 0 | 1 | 12346 |
| -1 | 10 | 12350 |
| -2 | 100 | 12400 |
| -3 | 1000 | 13000 |
| -4 | 10000 | 20000 |
| -5 | 100000 | 100000 |
Examples with negative self:
| ndigits | Granularity | -12345.6789.ceil(ndigits) |
|---|---|---|
| 0 | 1 | -12345 |
| -1 | 10 | -12340 |
| -2 | 100 | -12300 |
| -3 | 1000 | -12000 |
| -4 | 10000 | -10000 |
| -5 | 100000 | 0 |
When self is zero and ndigits is non-positive, returns Integer zero:
0.0.ceil(0) # => 0 0.0.ceil(-1) # => 0 0.0.ceil(-2) # => 0
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(2.1 / 0.7).ceil #=> 4 # Not 3 (because 2.1 / 0.7 # => 3.0000000000000004, not 3.0)
Related: Float#floor.
Source
static VALUE
flo_coerce(VALUE x, VALUE y)
{
return rb_assoc_new(rb_Float(y), x);
}
Returns a 2-element array containing other converted to a Float and self:
f = 3.14 # => 3.14 f.coerce(2) # => [2.0, 3.14] f.coerce(2.0) # => [2.0, 3.14] f.coerce(Rational(1, 2)) # => [0.5, 3.14] f.coerce(Complex(1, 0)) # => [1.0, 3.14]
Raises an exception if a type conversion fails.
Source
VALUE
rb_float_denominator(VALUE self)
{
double d = RFLOAT_VALUE(self);
VALUE r;
if (!isfinite(d))
return INT2FIX(1);
r = float_to_r(self);
return nurat_denominator(r);
}
Returns the denominator (always positive). The result is machine dependent.
See also Float#numerator.
Source
static VALUE
flo_divmod(VALUE x, VALUE y)
{
double fy, div, mod;
volatile VALUE a, b;
if (FIXNUM_P(y)) {
fy = (double)FIX2LONG(y);
}
else if (RB_BIGNUM_TYPE_P(y)) {
fy = rb_big2dbl(y);
}
else if (RB_FLOAT_TYPE_P(y)) {
fy = RFLOAT_VALUE(y);
}
else {
return rb_num_coerce_bin(x, y, id_divmod);
}
flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
a = dbl2ival(div);
b = DBL2NUM(mod);
return rb_assoc_new(a, b);
}
Returns a 2-element array [q, r], where
q = (self/other).floor # Quotient r = self % other # Remainder
Examples:
11.0.divmod(4) # => [2, 3.0] 11.0.divmod(-4) # => [-3, -1.0] -11.0.divmod(4) # => [-3, 1.0] -11.0.divmod(-4) # => [2, -3.0] 12.0.divmod(4) # => [3, 0.0] 12.0.divmod(-4) # => [-3, 0.0] -12.0.divmod(4) # => [-3, -0.0] -12.0.divmod(-4) # => [3, -0.0] 13.0.divmod(4.0) # => [3, 1.0] 13.0.divmod(Rational(4, 1)) # => [3, 1.0]
Source
VALUE
rb_float_eql(VALUE x, VALUE y)
{
if (RB_FLOAT_TYPE_P(y)) {
double a = RFLOAT_VALUE(x);
double b = RFLOAT_VALUE(y);
return RBOOL(a == b);
}
return Qfalse;
}
Returns true if other is a Float with the same value as self, false otherwise:
2.0.eql?(2.0) # => true 2.0.eql?(1.0) # => false 2.0.eql?(1) # => false 2.0.eql?(Rational(2, 1)) # => false 2.0.eql?(Complex(2, 0)) # => false
Float::NAN.eql?(Float::NAN) returns an implementation-dependent value.
Related: Float#== (performs type conversions).
Source
VALUE
rb_flo_is_finite_p(VALUE num)
{
double value = RFLOAT_VALUE(num);
return RBOOL(isfinite(value));
}
Returns true if self is not Infinity, -Infinity, or NaN, false otherwise:
f = 2.0 # => 2.0 f.finite? # => true f = 1.0/0.0 # => Infinity f.finite? # => false f = -1.0/0.0 # => -Infinity f.finite? # => false f = 0.0/0.0 # => NaN f.finite? # => false
Source
static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
int ndigits = flo_ndigits(argc, argv);
return rb_float_floor(num, ndigits);
}
Returns a float or integer that is a “floor” value for self, as specified by ndigits, which must be an integer-convertible object.
When self is zero, returns a zero value: a float if ndigits is positive, an integer otherwise:
f = 0.0 # => 0.0 f.floor(20) # => 0.0 f.floor(0) # => 0 f.floor(-20) # => 0
When self is non-zero and ndigits is positive, returns a float with ndigits digits after the decimal point (as available):
f = 12345.6789 f.floor(1) # => 12345.6 f.floor(3) # => 12345.678 f.floor(30) # => 12345.6789 f = -12345.6789 f.floor(1) # => -12345.7 f.floor(3) # => -12345.679 f.floor(30) # => -12345.6789
When self is non-zero and ndigits is non-positive, returns an integer value based on a computed granularity:
-
The granularity is
10 ** ndigits.abs. -
The returned value is the largest multiple of the granularity that is less than or equal to
self.
Examples with positive self:
| ndigits | Granularity | 12345.6789.floor(ndigits) |
|---|---|---|
| 0 | 1 | 12345 |
| -1 | 10 | 12340 |
| -2 | 100 | 12300 |
| -3 | 1000 | 12000 |
| -4 | 10000 | 10000 |
| -5 | 100000 | 0 |
Examples with negative self:
| ndigits | Granularity | -12345.6789.floor(ndigits) |
|---|---|---|
| 0 | 1 | -12346 |
| -1 | 10 | -12350 |
| -2 | 100 | -12400 |
| -3 | 1000 | -13000 |
| -4 | 10000 | -20000 |
| -5 | 100000 | -100000 |
| -6 | 1000000 | -1000000 |
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).floor # => 2 # Not 3, (because (0.3 / 0.1) # => 2.9999999999999996, not 3.0)
Related: Float#ceil.
Source
static VALUE
flo_hash(VALUE num)
{
return rb_dbl_hash(RFLOAT_VALUE(num));
}
Returns the integer hash value for self.
See also Object#hash.
Source
VALUE
rb_flo_is_infinite_p(VALUE num)
{
double value = RFLOAT_VALUE(num);
if (isinf(value)) {
return INT2FIX( value < 0 ? -1 : 1 );
}
return Qnil;
}
Returns:
-
1, if
selfisInfinity. -
-1 if
selfis-Infinity. -
nil, otherwise.
Examples:
f = 1.0/0.0 # => Infinity f.infinite? # => 1 f = -1.0/0.0 # => -Infinity f.infinite? # => -1 f = 1.0 # => 1.0 f.infinite? # => nil f = 0.0/0.0 # => NaN f.infinite? # => nil
Source
static VALUE
flo_is_nan_p(VALUE num)
{
double value = RFLOAT_VALUE(num);
return RBOOL(isnan(value));
}
Returns true if self is a NaN, false otherwise.
f = -1.0 #=> -1.0 f.nan? #=> false f = 0.0/0.0 #=> NaN f.nan? #=> true
Source
# File numeric.rb, line 416 def negative? Primitive.attr! :leaf Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) < 0.0)' end
Returns true if self is less than 0, false otherwise.
Source
static VALUE
flo_next_float(VALUE vx)
{
return flo_nextafter(vx, HUGE_VAL);
}
Returns the next-larger representable Float.
These examples show the internally stored values (64-bit hexadecimal) for each Float f and for the corresponding f.next_float:
f = 0.0 # 0x0000000000000000 f.next_float # 0x0000000000000001 f = 0.01 # 0x3f847ae147ae147b f.next_float # 0x3f847ae147ae147c
In the remaining examples here, the output is shown in the usual way (result to_s):
0.01.next_float # => 0.010000000000000002 1.0.next_float # => 1.0000000000000002 100.0.next_float # => 100.00000000000001 f = 0.01 (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.next_float }
Output:
0 0x1.47ae147ae147bp-7 0.01
1 0x1.47ae147ae147cp-7 0.010000000000000002
2 0x1.47ae147ae147dp-7 0.010000000000000004
3 0x1.47ae147ae147ep-7 0.010000000000000005
f = 0.0; 100.times { f += 0.1 }
f # => 9.99999999999998 # should be 10.0 in the ideal world.
10-f # => 1.9539925233402755e-14 # the floating point error.
10.0.next_float-10 # => 1.7763568394002505e-15 # 1 ulp (unit in the last place).
(10-f)/(10.0.next_float-10) # => 11.0 # the error is 11 ulp.
(10-f)/(10*Float::EPSILON) # => 8.8 # approximation of the above.
"%a" % 10 # => "0x1.4p+3"
"%a" % f # => "0x1.3fffffffffff5p+3" # the last hex digit is 5. 16 - 5 = 11 ulp.
Related: Float#prev_float
Source
VALUE
rb_float_numerator(VALUE self)
{
double d = RFLOAT_VALUE(self);
VALUE r;
if (!isfinite(d))
return self;
r = float_to_r(self);
return nurat_numerator(r);
}
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.
Source
# File numeric.rb, line 407 def positive? Primitive.attr! :leaf Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) > 0.0)' end
Returns true if self is greater than 0, false otherwise.
Source
static VALUE
flo_prev_float(VALUE vx)
{
return flo_nextafter(vx, -HUGE_VAL);
}
Returns the next-smaller representable Float.
These examples show the internally stored values (64-bit hexadecimal) for each Float f and for the corresponding f.pev_float:
f = 5e-324 # 0x0000000000000001 f.prev_float # 0x0000000000000000 f = 0.01 # 0x3f847ae147ae147b f.prev_float # 0x3f847ae147ae147a
In the remaining examples here, the output is shown in the usual way (result to_s):
0.01.prev_float # => 0.009999999999999998 1.0.prev_float # => 0.9999999999999999 100.0.prev_float # => 99.99999999999999 f = 0.01 (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.prev_float }
Output:
0 0x1.47ae147ae147bp-7 0.01 1 0x1.47ae147ae147ap-7 0.009999999999999998 2 0x1.47ae147ae1479p-7 0.009999999999999997 3 0x1.47ae147ae1478p-7 0.009999999999999995
Related: Float#next_float.
Source
static VALUE
flo_quo(VALUE x, VALUE y)
{
return num_funcall1(x, '/', y);
}
Returns the quotient from dividing self by other:
f = 3.14 f.quo(2) # => 1.57 f.quo(-2) # => -1.57 f.quo(Rational(2, 1)) # => 1.57 f.quo(Complex(2, 0)) # => (1.57+0.0i)
Source
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;
}
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.
Source
static VALUE
flo_round(int argc, VALUE *argv, VALUE num)
{
double number, f, x;
VALUE nd, opt;
int ndigits = 0;
enum ruby_num_rounding_mode mode;
if (rb_scan_args(argc, argv, "01:", &nd, &opt)) {
ndigits = NUM2INT(nd);
}
mode = rb_num_get_rounding_option(opt);
number = RFLOAT_VALUE(num);
if (number == 0.0) {
return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0);
}
if (ndigits < 0) {
return rb_int_round(flo_to_i(num), ndigits, mode);
}
if (ndigits == 0) {
x = ROUND_CALL(mode, round, (number, 1.0));
return dbl2ival(x);
}
if (isfinite(number)) {
int binexp;
frexp(number, &binexp);
if (float_round_overflow(ndigits, binexp)) return num;
if (float_round_underflow(ndigits, binexp)) return DBL2NUM(0);
if (!ACCURATE_POW10(ndigits)) {
return rb_flo_round_by_rational(num, ndigits, mode);
}
f = pow(10, ndigits);
x = ROUND_CALL(mode, round, (number, f));
return DBL2NUM(x / f);
}
return num;
}
Returns self rounded to the nearest value with a precision of ndigits decimal digits.
When ndigits is non-negative, returns a float with ndigits after the decimal point (as available):
f = 12345.6789 f.round(1) # => 12345.7 f.round(3) # => 12345.679 f = -12345.6789 f.round(1) # => -12345.7 f.round(3) # => -12345.679
When ndigits is negative, returns an integer with at least ndigits.abs trailing zeros:
f = 12345.6789 f.round(0) # => 12346 f.round(-3) # => 12000 f = -12345.6789 f.round(0) # => -12346 f.round(-3) # => -12000
If keyword argument half is given, and self is equidistant from the two candidate values, the rounding is according to the given half value:
-
:upornil: round away from zero:2.5.round(half: :up) # => 3 3.5.round(half: :up) # => 4 (-2.5).round(half: :up) # => -3
-
:down: round toward zero:2.5.round(half: :down) # => 2 3.5.round(half: :down) # => 3 (-2.5).round(half: :down) # => -2
-
:even: round toward the candidate whose last nonzero digit is even:2.5.round(half: :even) # => 2 3.5.round(half: :even) # => 4 (-2.5).round(half: :even) # => -2
Raises and exception if the value for half is invalid.
Related: Float#truncate.
Source
# File bundled-src/bigdecimal-4.0.1/lib/bigdecimal/util.rb, line 50 def to_d(precision=0) BigDecimal(self, precision) end
Returns the value of float as a BigDecimal. The precision parameter is used to determine the number of significant digits for the result. When precision is set to 0, the number of digits to represent the float being converted is determined automatically. The default precision is 0.
require 'bigdecimal' require 'bigdecimal/util' 0.5.to_d # => 0.5e0 1.234.to_d # => 0.1234e1 1.234.to_d(2) # => 0.12e1
See also Kernel.BigDecimal.
Source
# File numeric.rb, line 360 def to_f self end
Returns self (which is already a Float).
Source
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);
}
Returns self truncated to an Integer.
1.2.to_i # => 1 (-1.2).to_i # => -1
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).to_i # => 2 (!)
Source
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
}
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.
Source
static VALUE
flo_to_s(VALUE flt)
{
enum {decimal_mant = DBL_MANT_DIG-DBL_DIG};
enum {float_dig = DBL_DIG+1};
char buf[float_dig + roomof(decimal_mant, CHAR_BIT) + 10];
double value = RFLOAT_VALUE(flt);
VALUE s;
char *p, *e;
int sign, decpt, digs;
if (isinf(value)) {
static const char minf[] = "-Infinity";
const int pos = (value > 0); /* skip "-" */
return rb_usascii_str_new(minf+pos, strlen(minf)-pos);
}
else if (isnan(value))
return rb_usascii_str_new2("NaN");
p = ruby_dtoa(value, 0, 0, &decpt, &sign, &e);
s = sign ? rb_usascii_str_new_cstr("-") : rb_usascii_str_new(0, 0);
if ((digs = (int)(e - p)) >= (int)sizeof(buf)) digs = (int)sizeof(buf) - 1;
memcpy(buf, p, digs);
free(p);
if (decpt > 0) {
if (decpt < digs) {
memmove(buf + decpt + 1, buf + decpt, digs - decpt);
buf[decpt] = '.';
rb_str_cat(s, buf, digs + 1);
}
else if (decpt <= DBL_DIG) {
long len;
char *ptr;
rb_str_cat(s, buf, digs);
rb_str_resize(s, (len = RSTRING_LEN(s)) + decpt - digs + 2);
ptr = RSTRING_PTR(s) + len;
if (decpt > digs) {
memset(ptr, '0', decpt - digs);
ptr += decpt - digs;
}
memcpy(ptr, ".0", 2);
}
else {
goto exp;
}
}
else if (decpt > -4) {
long len;
char *ptr;
rb_str_cat(s, "0.", 2);
rb_str_resize(s, (len = RSTRING_LEN(s)) - decpt + digs);
ptr = RSTRING_PTR(s);
memset(ptr += len, '0', -decpt);
memcpy(ptr -= decpt, buf, digs);
}
else {
goto exp;
}
return s;
exp:
if (digs > 1) {
memmove(buf + 2, buf + 1, digs - 1);
}
else {
buf[2] = '0';
digs++;
}
buf[1] = '.';
rb_str_cat(s, buf, digs + 1);
rb_str_catf(s, "e%+03d", decpt - 1);
return s;
}
Returns a string containing a representation of self; depending of the value of self, the string representation may contain:
-
A fixed-point number.
3.14.to_s # => "3.14"
-
A number in “scientific notation” (containing an exponent).
(10.1**50).to_s # => "1.644631821843879e+50"
-
‘Infinity’.
(10.1**500).to_s # => "Infinity"
-
‘-Infinity’.
(-10.1**500).to_s # => "-Infinity"
-
‘NaN’ (indicating not-a-number).
(0.0/0.0).to_s # => "NaN"
Source
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);
}
Returns self truncated (toward zero) to a precision of ndigits decimal digits.
When ndigits is positive, returns a float with ndigits digits after the decimal point (as available):
f = 12345.6789 f.truncate(1) # => 12345.6 f.truncate(3) # => 12345.678 f = -12345.6789 f.truncate(1) # => -12345.6 f.truncate(3) # => -12345.678
When ndigits is negative, returns an integer with at least ndigits.abs trailing zeros:
f = 12345.6789 f.truncate(0) # => 12345 f.truncate(-3) # => 12000 f = -12345.6789 f.truncate(0) # => -12345 f.truncate(-3) # => -12000
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).truncate #=> 2 (!)
Related: Float#round.
Source
# File numeric.rb, line 398 def zero? Primitive.attr! :leaf Primitive.cexpr! 'RBOOL(FLOAT_ZERO_P(self))' end
Returns true if self is 0.0, false otherwise.