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.
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 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.
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.
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
Float#modulo
is an alias for Float#%
.
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 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_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));
}
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_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 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_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 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)
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 294
def -@
Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_uminus(self)'
end
Returns float
, negated.
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 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)
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 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_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 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_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 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.
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).
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 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.
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 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.
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 278
def abs
Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_abs(self)'
end
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
.
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
flo_ceil(int argc, VALUE *argv, VALUE num)
{
int ndigits = flo_ndigits(argc, argv);
return rb_float_ceil(num, ndigits);
}
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_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.
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
.
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]
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 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).
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
static VALUE
flo_floor(int argc, VALUE *argv, VALUE num)
{
int ndigits = flo_ndigits(argc, argv);
return rb_float_floor(num, ndigits);
}
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_hash(VALUE num)
{
return rb_dbl_hash(RFLOAT_VALUE(num));
}
Returns the integer hash value for self
.
See also Object#hash
.
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 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
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 283
def magnitude
Primitive.attr! 'inline'
Primitive.cexpr! 'rb_float_abs(self)'
end
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
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 327
def negative?
Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) < 0.0)'
end
Returns true
if float
is less than 0.
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
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
.
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 316
def positive?
Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(RFLOAT_VALUE(self) > 0.0)'
end
Returns true
if float
is greater than 0.
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
.
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)
Float#fdiv
is an alias for Float#quo
.
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
.
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;
}
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
.
# File tmp/rubies/ruby-3.1.2/ext/bigdecimal/lib/bigdecimal/util.rb, line 46
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 (the default is Float::DIG
).
require 'bigdecimal' require 'bigdecimal/util' 0.5.to_d # => 0.5e0 1.234.to_d(2) # => 0.12e1
See also BigDecimal::new
.
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 261
def to_f
return self
end
Since float
is already a Float
, returns self
.
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
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
.
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 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_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
.
# File tmp/rubies/ruby-3.1.2/numeric.rb, line 305
def zero?
Primitive.attr! 'inline'
Primitive.cexpr! 'RBOOL(FLOAT_ZERO_P(self))'
end
Returns true
if float
is 0.0.