A Float object represents a sometimes-inexact real number using the native architecture's double-precision floating point representation.
Floating point has a different arithmetic and is an inexact number. So you should know its esoteric system. See following:
You can create a Float object explicitly with:
You can convert certain objects to Floats with:
Method Float.
First, what's elsewhere. Class Float:
Inherits from class Numeric.
Here, class Float provides methods for:
finite?
Returns whether self
is finite.
hash
Returns the integer hash code for self
.
infinite?
Returns whether self
is infinite.
nan?
Returns whether self
is a NaN (not-a-number).
Returns whether self
is less than the given value.
Returns whether self
is less than or equal to the given value.
Returns a number indicating whether self
is less than, equal to, or greater than the given value.
Returns whether self
is greater than the given value.
Returns whether self
is greater than or equal to the given value.
*
Returns the product of self
and the given value.
Returns the value of self
raised to the power of the given value.
+
Returns the sum of self
and the given value.
-
Returns the difference of self
and the given value.
Returns the quotient of self
and the given value.
ceil
Returns the smallest number greater than or equal to self
.
coerce
Returns a 2-element array containing the given value converted to a Float and self
divmod
Returns a 2-element array containing the quotient and remainder results of dividing self
by the given value.
floor
Returns the greatest number smaller than or equal to self
.
next_float
Returns the next-larger representable Float.
prev_float
Returns the next-smaller representable Float.
quo
Returns the quotient from dividing self
by the given value.
round
Returns self
rounded to the nearest value, to a given precision.
truncate
Returns self
truncated to a given precision.
The minimum number of significant decimal digits in a double-precision floating point.
Usually defaults to 15.
The difference between 1 and the smallest double-precision floating point number greater than 1.
Usually defaults to 2.2204460492503131e-16.
An expression representing positive infinity.
The number of base digits for the double
data type.
Usually defaults to 53.
The largest possible integer in a double-precision floating point number.
Usually defaults to 1.7976931348623157e+308.
The largest positive exponent in a double-precision floating point where 10 raised to this power minus 1.
Usually defaults to 308.
The largest possible exponent value in a double-precision floating point.
Usually defaults to 1024.
The smallest positive normalized number in a double-precision floating point.
Usually defaults to 2.2250738585072014e-308.
If the platform supports denormalized numbers, there are numbers between zero and Float::MIN
. 0.0.next_float returns the smallest positive floating point number including denormalized numbers.
The smallest negative exponent in a double-precision floating point where 10 raised to this power minus 1.
Usually defaults to -307.
The smallest possible exponent value in a double-precision floating point.
Usually defaults to -1021.
An expression representing a value which is “not a number”.
The base of the floating point, or number of unique digits used to represent the number.
Usually defaults to 2 on most systems, which would represent a base-10 decimal.
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
Float#modulo
is an alias for Float#%
.
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 a new Float which is the product of self
and other
:
f = 3.14 f * 2 # => 6.28 f * 2.0 # => 6.28 f * Rational(1, 2) # => 1.57 f * Complex(2, 0) # => (6.28+0.0i)
VALUE rb_float_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) * (double)FIX2LONG(y)); } else if (RB_BIGNUM_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) * rb_big2dbl(y)); } else if (RB_FLOAT_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y)); } else { return rb_num_coerce_bin(x, y, '*'); } }
Raises self
to the power of other
:
f = 3.14 f ** 2 # => 9.8596 f ** -2 # => 0.1014239928597509 f ** 2.1 # => 11.054834900588839 f ** Rational(2, 1) # => 9.8596 f ** Complex(2, 0) # => (9.8596+0i)
VALUE rb_float_pow(VALUE x, VALUE y) { double dx, dy; if (y == INT2FIX(2)) { dx = RFLOAT_VALUE(x); return DBL2NUM(dx * dx); } else if (FIXNUM_P(y)) { dx = RFLOAT_VALUE(x); dy = (double)FIX2LONG(y); } else if (RB_BIGNUM_TYPE_P(y)) { dx = RFLOAT_VALUE(x); dy = rb_big2dbl(y); } else if (RB_FLOAT_TYPE_P(y)) { dx = RFLOAT_VALUE(x); dy = RFLOAT_VALUE(y); if (dx < 0 && dy != round(dy)) return rb_dbl_complex_new_polar_pi(pow(-dx, dy), dy); } else { return rb_num_coerce_bin(x, y, idPow); } return DBL2NUM(pow(dx, dy)); }
Returns a new Float which is the sum of self
and other
:
f = 3.14 f + 1 # => 4.140000000000001 f + 1.0 # => 4.140000000000001 f + Rational(1, 1) # => 4.140000000000001 f + Complex(1, 0) # => (4.140000000000001+0i)
VALUE rb_float_plus(VALUE x, VALUE y) { if (FIXNUM_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) + (double)FIX2LONG(y)); } else if (RB_BIGNUM_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) + rb_big2dbl(y)); } else if (RB_FLOAT_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y)); } else { return rb_num_coerce_bin(x, y, '+'); } }
Returns a new Float which is the difference of self
and other
:
f = 3.14 f - 1 # => 2.14 f - 1.0 # => 2.14 f - Rational(1, 1) # => 2.14 f - Complex(1, 0) # => (2.14+0i)
VALUE rb_float_minus(VALUE x, VALUE y) { if (FIXNUM_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) - (double)FIX2LONG(y)); } else if (RB_BIGNUM_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) - rb_big2dbl(y)); } else if (RB_FLOAT_TYPE_P(y)) { return DBL2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y)); } else { return rb_num_coerce_bin(x, y, '-'); } }
Returns float
, negated.
# File numeric.rb, line 294 def -@ Primitive.attr! 'inline' Primitive.cexpr! 'rb_float_uminus(self)' end
Returns a new Float which is the result of dividing self
by other
:
f = 3.14 f / 2 # => 1.57 f / 2.0 # => 1.57 f / Rational(2, 1) # => 1.57 f / Complex(2, 0) # => (1.57+0.0i)
VALUE rb_float_div(VALUE x, VALUE y) { double num = RFLOAT_VALUE(x); double den; double ret; if (FIXNUM_P(y)) { den = FIX2LONG(y); } else if (RB_BIGNUM_TYPE_P(y)) { den = rb_big2dbl(y); } else if (RB_FLOAT_TYPE_P(y)) { den = RFLOAT_VALUE(y); } else { return rb_num_coerce_bin(x, y, '/'); } ret = double_div_double(num, den); return DBL2NUM(ret); }
Returns true
if self
is numerically less than other
:
2.0 < 3 # => true 2.0 < 3.0 # => true 2.0 < Rational(3, 1) # => true 2.0 < 2.0 # => false
Float::NAN < Float::NAN
returns an implementation-dependent value.
static VALUE flo_lt(VALUE x, VALUE y) { double a, b; a = RFLOAT_VALUE(x); if (RB_INTEGER_TYPE_P(y)) { VALUE rel = rb_integer_float_cmp(y, x); if (FIXNUM_P(rel)) return RBOOL(-FIX2LONG(rel) < 0); return Qfalse; } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return rb_num_coerce_relop(x, y, '<'); } #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a < b); }
Returns true
if self
is numerically less than or equal to other
:
2.0 <= 3 # => true 2.0 <= 3.0 # => true 2.0 <= Rational(3, 1) # => true 2.0 <= 2.0 # => true 2.0 <= 1.0 # => false
Float::NAN <= Float::NAN
returns an implementation-dependent value.
static VALUE flo_le(VALUE x, VALUE y) { double a, b; a = RFLOAT_VALUE(x); if (RB_INTEGER_TYPE_P(y)) { VALUE rel = rb_integer_float_cmp(y, x); if (FIXNUM_P(rel)) return RBOOL(-FIX2LONG(rel) <= 0); return Qfalse; } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return rb_num_coerce_relop(x, y, idLE); } #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a <= b); }
Returns a value that depends on the numeric relation between self
and other
:
-1, if self
is less than other
.
0, if self
is equal to other
.
1, if self
is greater than other
.
nil
, if the two values are incommensurate.
Examples:
2.0 <=> 2 # => 0 2.0 <=> 2.0 # => 0 2.0 <=> Rational(2, 1) # => 0 2.0 <=> Complex(2, 0) # => 0 2.0 <=> 1.9 # => 1 2.0 <=> 2.1 # => -1 2.0 <=> 'foo' # => nil
This is the basis for the tests in the Comparable
module.
Float::NAN <=> Float::NAN
returns an implementation-dependent value.
static VALUE flo_cmp(VALUE x, VALUE y) { double a, b; VALUE i; a = RFLOAT_VALUE(x); if (isnan(a)) return Qnil; if (RB_INTEGER_TYPE_P(y)) { VALUE rel = rb_integer_float_cmp(y, x); if (FIXNUM_P(rel)) return LONG2FIX(-FIX2LONG(rel)); return rel; } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); } else { if (isinf(a) && (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); }
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).
MJIT_FUNC_EXPORTED VALUE rb_float_equal(VALUE x, VALUE y) { volatile double a, b; if (RB_INTEGER_TYPE_P(y)) { return rb_integer_float_eq(y, x); } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return num_equal(x, y); } a = RFLOAT_VALUE(x); #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a == b); }
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).
MJIT_FUNC_EXPORTED VALUE rb_float_equal(VALUE x, VALUE y) { volatile double a, b; if (RB_INTEGER_TYPE_P(y)) { return rb_integer_float_eq(y, x); } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return num_equal(x, y); } a = RFLOAT_VALUE(x); #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a == b); }
Returns true
if self
is numerically greater than other
:
2.0 > 1 # => true 2.0 > 1.0 # => true 2.0 > Rational(1, 2) # => true 2.0 > 2.0 # => false
Float::NAN > Float::NAN
returns an implementation-dependent value.
VALUE rb_float_gt(VALUE x, VALUE y) { double a, b; a = RFLOAT_VALUE(x); if (RB_INTEGER_TYPE_P(y)) { VALUE rel = rb_integer_float_cmp(y, x); if (FIXNUM_P(rel)) return RBOOL(-FIX2LONG(rel) > 0); return Qfalse; } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return rb_num_coerce_relop(x, y, '>'); } #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a > b); }
Returns true
if self
is numerically greater than or equal to other
:
2.0 >= 1 # => true 2.0 >= 1.0 # => true 2.0 >= Rational(1, 2) # => true 2.0 >= 2.0 # => true 2.0 >= 2.1 # => false
Float::NAN >= Float::NAN
returns an implementation-dependent value.
static VALUE flo_ge(VALUE x, VALUE y) { double a, b; a = RFLOAT_VALUE(x); if (RB_TYPE_P(y, T_FIXNUM) || RB_BIGNUM_TYPE_P(y)) { VALUE rel = rb_integer_float_cmp(y, x); if (FIXNUM_P(rel)) return RBOOL(-FIX2LONG(rel) >= 0); return Qfalse; } else if (RB_FLOAT_TYPE_P(y)) { b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(b)) return Qfalse; #endif } else { return rb_num_coerce_relop(x, y, idGE); } #if MSC_VERSION_BEFORE(1300) if (isnan(a)) return Qfalse; #endif return RBOOL(a >= b); }
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
.
# File numeric.rb, line 278 def abs Primitive.attr! 'inline' Primitive.cexpr! 'rb_float_abs(self)' end
Returns 0 if the value is positive, pi otherwise.
static VALUE float_arg(VALUE self) { if (isnan(RFLOAT_VALUE(self))) return self; if (f_tpositive_p(self)) return INT2FIX(0); return rb_const_get(rb_mMath, id_PI); }
Returns 0 if the value is positive, pi otherwise.
static VALUE float_arg(VALUE self) { if (isnan(RFLOAT_VALUE(self))) return self; if (f_tpositive_p(self)) return INT2FIX(0); return rb_const_get(rb_mMath, id_PI); }
Returns the smallest number greater than or equal to self
with a precision of ndigits
decimal digits.
When ndigits
is positive, returns a float with ndigits
digits after the decimal point (as available):
f = 12345.6789 f.ceil(1) # => 12345.7 f.ceil(3) # => 12345.679 f = -12345.6789 f.ceil(1) # => -12345.6 f.ceil(3) # => -12345.678
When ndigits
is non-positive, returns an integer with at least ndigits.abs
trailing zeros:
f = 12345.6789 f.ceil(0) # => 12346 f.ceil(-3) # => 13000 f = -12345.6789 f.ceil(0) # => -12345 f.ceil(-3) # => -12000
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(2.1 / 0.7).ceil #=> 4 (!)
Related: Float#floor
.
static VALUE flo_ceil(int argc, VALUE *argv, VALUE num) { int ndigits = flo_ndigits(argc, argv); return rb_float_ceil(num, ndigits); }
Returns a 2-element array containing other
converted to a Float and self
:
f = 3.14 # => 3.14 f.coerce(2) # => [2.0, 3.14] f.coerce(2.0) # => [2.0, 3.14] f.coerce(Rational(1, 2)) # => [0.5, 3.14] f.coerce(Complex(1, 0)) # => [1.0, 3.14]
Raises an exception if a type conversion fails.
static VALUE flo_coerce(VALUE x, VALUE y) { return rb_assoc_new(rb_Float(y), x); }
Returns the denominator (always positive). The result is machine dependent.
See also Float#numerator
.
VALUE rb_float_denominator(VALUE self) { double d = RFLOAT_VALUE(self); VALUE r; if (!isfinite(d)) return INT2FIX(1); r = float_to_r(self); return nurat_denominator(r); }
Returns a 2-element array [q, r]
, where
q = (self/other).floor # Quotient r = self % other # Remainder
Examples:
11.0.divmod(4) # => [2, 3.0] 11.0.divmod(-4) # => [-3, -1.0] -11.0.divmod(4) # => [-3, 1.0] -11.0.divmod(-4) # => [2, -3.0] 12.0.divmod(4) # => [3, 0.0] 12.0.divmod(-4) # => [-3, 0.0] -12.0.divmod(4) # => [-3, -0.0] -12.0.divmod(-4) # => [3, -0.0] 13.0.divmod(4.0) # => [3, 1.0] 13.0.divmod(Rational(4, 1)) # => [3, 1.0]
static VALUE flo_divmod(VALUE x, VALUE y) { double fy, div, mod; volatile VALUE a, b; if (FIXNUM_P(y)) { fy = (double)FIX2LONG(y); } else if (RB_BIGNUM_TYPE_P(y)) { fy = rb_big2dbl(y); } else if (RB_FLOAT_TYPE_P(y)) { fy = RFLOAT_VALUE(y); } else { return rb_num_coerce_bin(x, y, id_divmod); } flodivmod(RFLOAT_VALUE(x), fy, &div, &mod); a = dbl2ival(div); b = DBL2NUM(mod); return rb_assoc_new(a, b); }
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).
MJIT_FUNC_EXPORTED VALUE rb_float_eql(VALUE x, VALUE y) { if (RB_FLOAT_TYPE_P(y)) { double a = RFLOAT_VALUE(x); double b = RFLOAT_VALUE(y); #if MSC_VERSION_BEFORE(1300) if (isnan(a) || isnan(b)) return Qfalse; #endif return RBOOL(a == b); } return Qfalse; }
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)
Float#fdiv
is an alias for Float#quo
.
static VALUE flo_quo(VALUE x, VALUE y) { return num_funcall1(x, '/', y); }
Returns true
if self
is not Infinity
, -Infinity
, or Nan
, false
otherwise:
f = 2.0 # => 2.0 f.finite? # => true f = 1.0/0.0 # => Infinity f.finite? # => false f = -1.0/0.0 # => -Infinity f.finite? # => false f = 0.0/0.0 # => NaN f.finite? # => false
VALUE rb_flo_is_finite_p(VALUE num) { double value = RFLOAT_VALUE(num); return RBOOL(isfinite(value)); }
Returns the largest number less than or equal to self
with a precision of ndigits
decimal digits.
When ndigits
is positive, returns a float with ndigits
digits after the decimal point (as available):
f = 12345.6789 f.floor(1) # => 12345.6 f.floor(3) # => 12345.678 f = -12345.6789 f.floor(1) # => -12345.7 f.floor(3) # => -12345.679
When ndigits
is non-positive, returns an integer with at least ndigits.abs
trailing zeros:
f = 12345.6789 f.floor(0) # => 12345 f.floor(-3) # => 12000 f = -12345.6789 f.floor(0) # => -12346 f.floor(-3) # => -13000
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).floor #=> 2 (!)
Related: Float#ceil
.
static VALUE flo_floor(int argc, VALUE *argv, VALUE num) { int ndigits = flo_ndigits(argc, argv); return rb_float_floor(num, ndigits); }
Returns the integer hash value for self
.
See also Object#hash
.
static VALUE flo_hash(VALUE num) { return rb_dbl_hash(RFLOAT_VALUE(num)); }
Returns:
1, if self
is Infinity
.
-1 if self
is -Infinity
.
nil
, otherwise.
Examples:
f = 1.0/0.0 # => Infinity f.infinite? # => 1 f = -1.0/0.0 # => -Infinity f.infinite? # => -1 f = 1.0 # => 1.0 f.infinite? # => nil f = 0.0/0.0 # => NaN f.infinite? # => nil
VALUE rb_flo_is_infinite_p(VALUE num) { double value = RFLOAT_VALUE(num); if (isinf(value)) { return INT2FIX( value < 0 ? -1 : 1 ); } return Qnil; }
# File numeric.rb, line 283 def magnitude Primitive.attr! 'inline' Primitive.cexpr! 'rb_float_abs(self)' end
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
Float#modulo
is an alias for Float#%
.
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 true
if self
is a NaN, false
otherwise.
f = -1.0 #=> -1.0 f.nan? #=> false f = 0.0/0.0 #=> NaN f.nan? #=> true
static VALUE flo_is_nan_p(VALUE num) { double value = RFLOAT_VALUE(num); return RBOOL(isnan(value)); }
Returns true
if float
is less than 0.
# File numeric.rb, line 327 def negative? Primitive.attr! 'inline' Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) < 0.0)' end
Returns the next-larger representable Float.
These examples show the internally stored values (64-bit hexadecimal) for each Float f
and for the corresponding f.next_float
:
f = 0.0 # 0x0000000000000000 f.next_float # 0x0000000000000001 f = 0.01 # 0x3f847ae147ae147b f.next_float # 0x3f847ae147ae147c
In the remaining examples here, the output is shown in the usual way (result to_s
):
0.01.next_float # => 0.010000000000000002 1.0.next_float # => 1.0000000000000002 100.0.next_float # => 100.00000000000001 f = 0.01 (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.next_float }
Output:
0 0x1.47ae147ae147bp-7 0.01 1 0x1.47ae147ae147cp-7 0.010000000000000002 2 0x1.47ae147ae147dp-7 0.010000000000000004 3 0x1.47ae147ae147ep-7 0.010000000000000005 f = 0.0; 100.times { f += 0.1 } f # => 9.99999999999998 # should be 10.0 in the ideal world. 10-f # => 1.9539925233402755e-14 # the floating point error. 10.0.next_float-10 # => 1.7763568394002505e-15 # 1 ulp (unit in the last place). (10-f)/(10.0.next_float-10) # => 11.0 # the error is 11 ulp. (10-f)/(10*Float::EPSILON) # => 8.8 # approximation of the above. "%a" % 10 # => "0x1.4p+3" "%a" % f # => "0x1.3fffffffffff5p+3" # the last hex digit is 5. 16 - 5 = 11 ulp.
Related: Float#prev_float
static VALUE flo_next_float(VALUE vx) { return flo_nextafter(vx, HUGE_VAL); }
Returns the numerator. The result is machine dependent.
n = 0.3.numerator #=> 5404319552844595 d = 0.3.denominator #=> 18014398509481984 n.fdiv(d) #=> 0.3
See also Float#denominator
.
VALUE rb_float_numerator(VALUE self) { double d = RFLOAT_VALUE(self); VALUE r; if (!isfinite(d)) return self; r = float_to_r(self); return nurat_numerator(r); }
Returns 0 if the value is positive, pi otherwise.
static VALUE float_arg(VALUE self) { if (isnan(RFLOAT_VALUE(self))) return self; if (f_tpositive_p(self)) return INT2FIX(0); return rb_const_get(rb_mMath, id_PI); }
Returns true
if float
is greater than 0.
# File numeric.rb, line 316 def positive? Primitive.attr! 'inline' Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) > 0.0)' end
Returns the next-smaller representable Float.
These examples show the internally stored values (64-bit hexadecimal) for each Float f
and for the corresponding f.pev_float
:
f = 5e-324 # 0x0000000000000001 f.prev_float # 0x0000000000000000 f = 0.01 # 0x3f847ae147ae147b f.prev_float # 0x3f847ae147ae147a
In the remaining examples here, the output is shown in the usual way (result to_s
):
0.01.prev_float # => 0.009999999999999998 1.0.prev_float # => 0.9999999999999999 100.0.prev_float # => 99.99999999999999 f = 0.01 (0..3).each_with_index {|i| printf "%2d %-20a %s\n", i, f, f.to_s; f = f.prev_float }
Output:
0 0x1.47ae147ae147bp-7 0.01 1 0x1.47ae147ae147ap-7 0.009999999999999998 2 0x1.47ae147ae1479p-7 0.009999999999999997 3 0x1.47ae147ae1478p-7 0.009999999999999995
Related: Float#next_float
.
static VALUE flo_prev_float(VALUE vx) { return flo_nextafter(vx, -HUGE_VAL); }
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)
Float#fdiv
is an alias for Float#quo
.
static VALUE flo_quo(VALUE x, VALUE y) { return num_funcall1(x, '/', y); }
Returns a simpler approximation of the value (flt-|eps| <= result <= flt+|eps|). If the optional argument eps
is not given, it will be chosen automatically.
0.3.rationalize #=> (3/10) 1.333.rationalize #=> (1333/1000) 1.333.rationalize(0.01) #=> (4/3)
See also Float#to_r
.
static VALUE float_rationalize(int argc, VALUE *argv, VALUE self) { double d = RFLOAT_VALUE(self); VALUE rat; int neg = d < 0.0; if (neg) self = DBL2NUM(-d); if (rb_check_arity(argc, 0, 1)) { rat = rb_flt_rationalize_with_prec(self, argv[0]); } else { rat = rb_flt_rationalize(self); } if (neg) RATIONAL_SET_NUM(rat, rb_int_uminus(RRATIONAL(rat)->num)); return rat; }
Returns self
rounded to the nearest value with a precision of ndigits
decimal digits.
When ndigits
is non-negative, returns a float with ndigits
after the decimal point (as available):
f = 12345.6789 f.round(1) # => 12345.7 f.round(3) # => 12345.679 f = -12345.6789 f.round(1) # => -12345.7 f.round(3) # => -12345.679
When ndigits
is negative, returns an integer with at least ndigits.abs
trailing zeros:
f = 12345.6789 f.round(0) # => 12346 f.round(-3) # => 12000 f = -12345.6789 f.round(0) # => -12346 f.round(-3) # => -12000
If keyword argument half
is given, and self
is equidistant from the two candidate values, the rounding is according to the given half
value:
:up
or nil
: round away from zero:
2.5.round(half: :up) # => 3 3.5.round(half: :up) # => 4 (-2.5).round(half: :up) # => -3
:down
: round toward zero:
2.5.round(half: :down) # => 2 3.5.round(half: :down) # => 3 (-2.5).round(half: :down) # => -2
:even
: round toward the candidate whose last nonzero digit is even:
2.5.round(half: :even) # => 2 3.5.round(half: :even) # => 4 (-2.5).round(half: :even) # => -2
Raises and exception if the value for half
is invalid.
Related: Float#truncate
.
static VALUE flo_round(int argc, VALUE *argv, VALUE num) { double number, f, x; VALUE nd, opt; int ndigits = 0; enum ruby_num_rounding_mode mode; if (rb_scan_args(argc, argv, "01:", &nd, &opt)) { ndigits = NUM2INT(nd); } mode = rb_num_get_rounding_option(opt); number = RFLOAT_VALUE(num); if (number == 0.0) { return ndigits > 0 ? DBL2NUM(number) : INT2FIX(0); } if (ndigits < 0) { return rb_int_round(flo_to_i(num), ndigits, mode); } if (ndigits == 0) { x = ROUND_CALL(mode, round, (number, 1.0)); return dbl2ival(x); } if (isfinite(number)) { int binexp; frexp(number, &binexp); if (float_round_overflow(ndigits, binexp)) return num; if (float_round_underflow(ndigits, binexp)) return DBL2NUM(0); if (ndigits > 14) { /* In this case, pow(10, ndigits) may not be accurate. */ return rb_flo_round_by_rational(argc, argv, num); } f = pow(10, ndigits); x = ROUND_CALL(mode, round, (number, f)); return DBL2NUM(x / f); } return num; }
Since float
is already a Float
, returns self
.
# File numeric.rb, line 261 def to_f return self end
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 (!)
Float#to_int
is an alias for Float#to_i
.
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 (!)
Float#to_int
is an alias for Float#to_i
.
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 the value as a rational.
2.0.to_r #=> (2/1) 2.5.to_r #=> (5/2) -0.75.to_r #=> (-3/4) 0.0.to_r #=> (0/1) 0.3.to_r #=> (5404319552844595/18014398509481984)
NOTE: 0.3.to_r isn't the same as “0.3”.to_r. The latter is equivalent to “3/10”.to_r, but the former isn't so.
0.3.to_r == 3/10r #=> false "0.3".to_r == 3/10r #=> true
See also Float#rationalize
.
static VALUE float_to_r(VALUE self) { VALUE f; int n; float_decode_internal(self, &f, &n); #if FLT_RADIX == 2 if (n == 0) return rb_rational_new1(f); if (n > 0) return rb_rational_new1(rb_int_lshift(f, INT2FIX(n))); n = -n; return rb_rational_new2(f, rb_int_lshift(ONE, INT2FIX(n))); #else f = rb_int_mul(f, rb_int_pow(INT2FIX(FLT_RADIX), n)); if (RB_TYPE_P(f, T_RATIONAL)) return f; return rb_rational_new1(f); #endif }
Returns a string containing a representation of self
; depending of the value of self
, the string representation may contain:
A fixed-point number.
A number in “scientific notation” (containing an exponent).
'Infinity'.
'-Infinity'.
'NaN' (indicating not-a-number).
3.14.to_s # => “3.14” (10.1**50).to_s # => “1.644631821843879e+50” (10.1**500).to_s # => “Infinity” (-10.1**500).to_s # => “-Infinity” (0.0/0.0).to_s # => “NaN”
static VALUE flo_to_s(VALUE flt) { enum {decimal_mant = DBL_MANT_DIG-DBL_DIG}; enum {float_dig = DBL_DIG+1}; char buf[float_dig + (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; }
Returns self
truncated (toward zero) to a precision of ndigits
decimal digits.
When ndigits
is positive, returns a float with ndigits
digits after the decimal point (as available):
f = 12345.6789 f.truncate(1) # => 12345.6 f.truncate(3) # => 12345.678 f = -12345.6789 f.truncate(1) # => -12345.6 f.truncate(3) # => -12345.678
When ndigits
is negative, returns an integer with at least ndigits.abs
trailing zeros:
f = 12345.6789 f.truncate(0) # => 12345 f.truncate(-3) # => 12000 f = -12345.6789 f.truncate(0) # => -12345 f.truncate(-3) # => -12000
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).truncate #=> 2 (!)
Related: Float#round
.
static VALUE flo_truncate(int argc, VALUE *argv, VALUE num) { if (signbit(RFLOAT_VALUE(num))) return flo_ceil(argc, argv, num); else return flo_floor(argc, argv, num); }