Float objects represent real numbers using the native architecture‘s double-precision floating point representation.
ROUNDS | = | INT2FIX(FLT_ROUNDS) |
RADIX | = | INT2FIX(FLT_RADIX) |
MANT_DIG | = | INT2FIX(DBL_MANT_DIG) |
DIG | = | INT2FIX(DBL_DIG) |
MIN_EXP | = | INT2FIX(DBL_MIN_EXP) |
MAX_EXP | = | INT2FIX(DBL_MAX_EXP) |
MIN_10_EXP | = | INT2FIX(DBL_MIN_10_EXP) |
MAX_10_EXP | = | INT2FIX(DBL_MAX_10_EXP) |
MIN | = | rb_float_new(DBL_MIN) |
MAX | = | rb_float_new(DBL_MAX) |
EPSILON | = | rb_float_new(DBL_EPSILON) |
Convert obj to a float.
/* * call-seq: * Float.induced_from(obj) => float * * Convert <code>obj</code> to a float. */ static VALUE rb_flo_induced_from(klass, x) VALUE klass, x; { switch (TYPE(x)) { case T_FIXNUM: case T_BIGNUM: return rb_funcall(x, rb_intern("to_f"), 0); case T_FLOAT: return x; default: rb_raise(rb_eTypeError, "failed to convert %s into Float", rb_obj_classname(x)); } }
Return the modulo after division of flt by other.
6543.21.modulo(137) #=> 104.21 6543.21.modulo(137.24) #=> 92.9299999999996
/* * call-seq: * flt % other => float * flt.modulo(other) => float * * Return the modulo after division of <code>flt</code> by <code>other</code>. * * 6543.21.modulo(137) #=> 104.21 * 6543.21.modulo(137.24) #=> 92.9299999999996 */ static VALUE flo_mod(x, y) VALUE x, y; { double fy, mod; switch (TYPE(y)) { case T_FIXNUM: fy = (double)FIX2LONG(y); break; case T_BIGNUM: fy = rb_big2dbl(y); break; case T_FLOAT: fy = RFLOAT(y)->value; break; default: return rb_num_coerce_bin(x, y); } flodivmod(RFLOAT(x)->value, fy, 0, &mod); return rb_float_new(mod); }
Returns a new float which is the product of float and other.
/* * call-seq: * float * other => float * * Returns a new float which is the product of <code>float</code> * and <code>other</code>. */ static VALUE flo_mul(x, y) VALUE x, y; { switch (TYPE(y)) { case T_FIXNUM: return rb_float_new(RFLOAT(x)->value * (double)FIX2LONG(y)); case T_BIGNUM: return rb_float_new(RFLOAT(x)->value * rb_big2dbl(y)); case T_FLOAT: return rb_float_new(RFLOAT(x)->value * RFLOAT(y)->value); default: return rb_num_coerce_bin(x, y); } }
flt ** other => float
Raises float the other power.
/* * call-seq: * * flt ** other => float * * Raises <code>float</code> the <code>other</code> power. */ static VALUE flo_pow(x, y) VALUE x, y; { switch (TYPE(y)) { case T_FIXNUM: return rb_float_new(pow(RFLOAT(x)->value, (double)FIX2LONG(y))); case T_BIGNUM: return rb_float_new(pow(RFLOAT(x)->value, rb_big2dbl(y))); case T_FLOAT: return rb_float_new(pow(RFLOAT(x)->value, RFLOAT(y)->value)); default: return rb_num_coerce_bin(x, y); } }
Returns a new float which is the sum of float and other.
/* * call-seq: * float + other => float * * Returns a new float which is the sum of <code>float</code> * and <code>other</code>. */ static VALUE flo_plus(x, y) VALUE x, y; { switch (TYPE(y)) { case T_FIXNUM: return rb_float_new(RFLOAT(x)->value + (double)FIX2LONG(y)); case T_BIGNUM: return rb_float_new(RFLOAT(x)->value + rb_big2dbl(y)); case T_FLOAT: return rb_float_new(RFLOAT(x)->value + RFLOAT(y)->value); default: return rb_num_coerce_bin(x, y); } }
Returns a new float which is the difference of float and other.
/* * call-seq: * float + other => float * * Returns a new float which is the difference of <code>float</code> * and <code>other</code>. */ static VALUE flo_minus(x, y) VALUE x, y; { switch (TYPE(y)) { case T_FIXNUM: return rb_float_new(RFLOAT(x)->value - (double)FIX2LONG(y)); case T_BIGNUM: return rb_float_new(RFLOAT(x)->value - rb_big2dbl(y)); case T_FLOAT: return rb_float_new(RFLOAT(x)->value - RFLOAT(y)->value); default: return rb_num_coerce_bin(x, y); } }
Returns float, negated.
/* * call-seq: * -float => float * * Returns float, negated. */ static VALUE flo_uminus(flt) VALUE flt; { return rb_float_new(-RFLOAT(flt)->value); }
Returns a new float which is the result of dividing float by other.
/* * call-seq: * float / other => float * * Returns a new float which is the result of dividing * <code>float</code> by <code>other</code>. */ static VALUE flo_div(x, y) VALUE x, y; { long f_y; double d; switch (TYPE(y)) { case T_FIXNUM: f_y = FIX2LONG(y); return rb_float_new(RFLOAT(x)->value / (double)f_y); case T_BIGNUM: d = rb_big2dbl(y); return rb_float_new(RFLOAT(x)->value / d); case T_FLOAT: return rb_float_new(RFLOAT(x)->value / RFLOAT(y)->value); default: return rb_num_coerce_bin(x, y); } }
true if flt is less than other.
/* * call-seq: * flt < other => true or false * * <code>true</code> if <code>flt</code> is less than <code>other</code>. */ static VALUE flo_lt(x, y) VALUE x, y; { double a, b; a = RFLOAT(x)->value; switch (TYPE(y)) { case T_FIXNUM: b = (double)FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; if (isnan(b)) return Qfalse; break; default: return rb_num_coerce_relop(x, y); } if (isnan(a)) return Qfalse; return (a < b)?Qtrue:Qfalse; }
true if flt is less than or equal to other.
/* * call-seq: * flt <= other => true or false * * <code>true</code> if <code>flt</code> is less than * or equal to <code>other</code>. */ static VALUE flo_le(x, y) VALUE x, y; { double a, b; a = RFLOAT(x)->value; switch (TYPE(y)) { case T_FIXNUM: b = (double)FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; if (isnan(b)) return Qfalse; break; default: return rb_num_coerce_relop(x, y); } if (isnan(a)) return Qfalse; return (a <= b)?Qtrue:Qfalse; }
Returns -1, 0, or +1 depending on whether flt is less than, equal to, or greater than numeric. This is the basis for the tests in Comparable.
/* * call-seq: * flt <=> numeric => -1, 0, +1 * * Returns -1, 0, or +1 depending on whether <i>flt</i> is less than, * equal to, or greater than <i>numeric</i>. This is the basis for the * tests in <code>Comparable</code>. */ static VALUE flo_cmp(x, y) VALUE x, y; { double a, b; a = RFLOAT(x)->value; switch (TYPE(y)) { case T_FIXNUM: b = (double)FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; break; default: return rb_num_coerce_cmp(x, y); } return rb_dbl_cmp(a, b); }
Returns true only if obj has the same value as flt. Contrast this with Float#eql?, which requires obj to be a Float.
1.0 == 1 #=> true
/* * call-seq: * flt == obj => true or false * * Returns <code>true</code> only if <i>obj</i> has the same value * as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which * requires <i>obj</i> to be a <code>Float</code>. * * 1.0 == 1 #=> true * */ static VALUE flo_eq(x, y) VALUE x, y; { volatile double a, b; switch (TYPE(y)) { case T_FIXNUM: b = FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; if (isnan(b)) return Qfalse; break; default: return num_equal(x, y); } a = RFLOAT(x)->value; if (isnan(a)) return Qfalse; return (a == b)?Qtrue:Qfalse; }
true if flt is greater than other.
/* * call-seq: * flt > other => true or false * * <code>true</code> if <code>flt</code> is greater than <code>other</code>. */ static VALUE flo_gt(x, y) VALUE x, y; { double a, b; a = RFLOAT(x)->value; switch (TYPE(y)) { case T_FIXNUM: b = (double)FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; if (isnan(b)) return Qfalse; break; default: return rb_num_coerce_relop(x, y); } if (isnan(a)) return Qfalse; return (a > b)?Qtrue:Qfalse; }
true if flt is greater than or equal to other.
/* * call-seq: * flt >= other => true or false * * <code>true</code> if <code>flt</code> is greater than * or equal to <code>other</code>. */ static VALUE flo_ge(x, y) VALUE x, y; { double a, b; a = RFLOAT(x)->value; switch (TYPE(y)) { case T_FIXNUM: b = (double)FIX2LONG(y); break; case T_BIGNUM: b = rb_big2dbl(y); break; case T_FLOAT: b = RFLOAT(y)->value; if (isnan(b)) return Qfalse; break; default: return rb_num_coerce_relop(x, y); } if (isnan(a)) return Qfalse; return (a >= b)?Qtrue:Qfalse; }
Returns the absolute value of flt.
(-34.56).abs #=> 34.56 -34.56.abs #=> 34.56
/* * call-seq: * flt.abs => float * * Returns the absolute value of <i>flt</i>. * * (-34.56).abs #=> 34.56 * -34.56.abs #=> 34.56 * */ static VALUE flo_abs(flt) VALUE flt; { double val = fabs(RFLOAT(flt)->value); return rb_float_new(val); }
Returns the smallest Integer greater than or equal to flt.
1.2.ceil #=> 2 2.0.ceil #=> 2 (-1.2).ceil #=> -1 (-2.0).ceil #=> -2
/* * call-seq: * flt.ceil => integer * * Returns the smallest <code>Integer</code> greater than or equal to * <i>flt</i>. * * 1.2.ceil #=> 2 * 2.0.ceil #=> 2 * (-1.2).ceil #=> -1 * (-2.0).ceil #=> -2 */ static VALUE flo_ceil(num) VALUE num; { double f = ceil(RFLOAT(num)->value); long val; if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }
MISSING: documentation
/* * MISSING: documentation */ static VALUE flo_coerce(x, y) VALUE x, y; { return rb_assoc_new(rb_Float(y), x); }
See Numeric#divmod.
/* * call-seq: * flt.divmod(numeric) => array * * See <code>Numeric#divmod</code>. */ static VALUE flo_divmod(x, y) VALUE x, y; { double fy, div, mod, val; volatile VALUE a, b; switch (TYPE(y)) { case T_FIXNUM: fy = (double)FIX2LONG(y); break; case T_BIGNUM: fy = rb_big2dbl(y); break; case T_FLOAT: fy = RFLOAT(y)->value; break; default: return rb_num_coerce_bin(x, y); } flodivmod(RFLOAT(x)->value, fy, &div, &mod); if (FIXABLE(div)) { val = round(div); a = LONG2FIX(val); } else { a = rb_dbl2big(div); } b = rb_float_new(mod); return rb_assoc_new(a, b); }
Returns true only if obj is a Float with the same value as flt. Contrast this with Float#==, which performs type conversions.
1.0.eql?(1) #=> false
/* * call-seq: * flt.eql?(obj) => true or false * * Returns <code>true</code> only if <i>obj</i> is a * <code>Float</code> with the same value as <i>flt</i>. Contrast this * with <code>Float#==</code>, which performs type conversions. * * 1.0.eql?(1) #=> false */ static VALUE flo_eql(x, y) VALUE x, y; { if (TYPE(y) == T_FLOAT) { double a = RFLOAT(x)->value; double b = RFLOAT(y)->value; if (isnan(a) || isnan(b)) return Qfalse; if (a == b) return Qtrue; } return Qfalse; }
Returns true if flt is a valid IEEE floating point number (it is not infinite, and nan? is false).
/* * call-seq: * flt.finite? -> true or false * * Returns <code>true</code> if <i>flt</i> is a valid IEEE floating * point number (it is not infinite, and <code>nan?</code> is * <code>false</code>). * */ static VALUE flo_is_finite_p(num) VALUE num; { double value = RFLOAT(num)->value; #if HAVE_FINITE if (!finite(value)) return Qfalse; #else if (isinf(value) || isnan(value)) return Qfalse; #endif return Qtrue; }
Returns the largest integer less than or equal to flt.
1.2.floor #=> 1 2.0.floor #=> 2 (-1.2).floor #=> -2 (-2.0).floor #=> -2
/* * call-seq: * flt.floor => integer * * Returns the largest integer less than or equal to <i>flt</i>. * * 1.2.floor #=> 1 * 2.0.floor #=> 2 * (-1.2).floor #=> -2 * (-2.0).floor #=> -2 */ static VALUE flo_floor(num) VALUE num; { double f = floor(RFLOAT(num)->value); long val; if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }
Returns a hash code for this float.
/* * call-seq: * flt.hash => integer * * Returns a hash code for this float. */ static VALUE flo_hash(num) VALUE num; { double d; char *c; int i, hash; d = RFLOAT(num)->value; if (d == 0) d = fabs(d); c = (char*)&d; for (hash=0, i=0; i<sizeof(double);i++) { hash = (hash * 971) ^ (unsigned char)c[i]; } if (hash < 0) hash = -hash; return INT2FIX(hash); }
Returns nil, -1, or +1 depending on whether flt is finite, -infinity, or +infinity.
(0.0).infinite? #=> nil (-1.0/0.0).infinite? #=> -1 (+1.0/0.0).infinite? #=> 1
/* * call-seq: * flt.infinite? -> nil, -1, +1 * * Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i> * is finite, -infinity, or +infinity. * * (0.0).infinite? #=> nil * (-1.0/0.0).infinite? #=> -1 * (+1.0/0.0).infinite? #=> 1 */ static VALUE flo_is_infinite_p(num) VALUE num; { double value = RFLOAT(num)->value; if (isinf(value)) { return INT2FIX( value < 0 ? -1 : 1 ); } return Qnil; }
Return the modulo after division of flt by other.
6543.21.modulo(137) #=> 104.21 6543.21.modulo(137.24) #=> 92.9299999999996
/* * call-seq: * flt % other => float * flt.modulo(other) => float * * Return the modulo after division of <code>flt</code> by <code>other</code>. * * 6543.21.modulo(137) #=> 104.21 * 6543.21.modulo(137.24) #=> 92.9299999999996 */ static VALUE flo_mod(x, y) VALUE x, y; { double fy, mod; switch (TYPE(y)) { case T_FIXNUM: fy = (double)FIX2LONG(y); break; case T_BIGNUM: fy = rb_big2dbl(y); break; case T_FLOAT: fy = RFLOAT(y)->value; break; default: return rb_num_coerce_bin(x, y); } flodivmod(RFLOAT(x)->value, fy, 0, &mod); return rb_float_new(mod); }
Returns true if flt is an invalid IEEE floating point number.
a = -1.0 #=> -1.0 a.nan? #=> false a = 0.0/0.0 #=> NaN a.nan? #=> true
/* * call-seq: * flt.nan? -> true or false * * Returns <code>true</code> if <i>flt</i> is an invalid IEEE floating * point number. * * a = -1.0 #=> -1.0 * a.nan? #=> false * a = 0.0/0.0 #=> NaN * a.nan? #=> true */ static VALUE flo_is_nan_p(num) VALUE num; { double value = RFLOAT(num)->value; return isnan(value) ? Qtrue : Qfalse; }
Rounds flt to the nearest integer. Equivalent to:
def round return (self+0.5).floor if self > 0.0 return (self-0.5).ceil if self < 0.0 return 0 end 1.5.round #=> 2 (-1.5).round #=> -2
/* * call-seq: * flt.round => integer * * Rounds <i>flt</i> to the nearest integer. Equivalent to: * * def round * return (self+0.5).floor if self > 0.0 * return (self-0.5).ceil if self < 0.0 * return 0 * end * * 1.5.round #=> 2 * (-1.5).round #=> -2 * */ static VALUE flo_round(num) VALUE num; { double f = RFLOAT(num)->value; long val; f = round(f); if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }
As flt is already a float, returns self.
/* * call-seq: * flt.to_f => flt * * As <code>flt</code> is already a float, returns <i>self</i>. */ static VALUE flo_to_f(num) VALUE num; { return num; }
Returns flt truncated to an Integer.
/* * call-seq: * flt.to_i => integer * flt.to_int => integer * flt.truncate => integer * * Returns <i>flt</i> truncated to an <code>Integer</code>. */ static VALUE flo_truncate(num) VALUE num; { double f = RFLOAT(num)->value; long val; if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }
Returns flt truncated to an Integer.
/* * call-seq: * flt.to_i => integer * flt.to_int => integer * flt.truncate => integer * * Returns <i>flt</i> truncated to an <code>Integer</code>. */ static VALUE flo_truncate(num) VALUE num; { double f = RFLOAT(num)->value; long val; if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }
Returns a string containing a representation of self. As well as a fixed or exponential form of the number, the call may return ``NaN’’, ``Infinity’’, and ``-Infinity’’.
/* * call-seq: * flt.to_s => string * * Returns a string containing a representation of self. As well as a * fixed or exponential form of the number, the call may return * ``<code>NaN</code>'', ``<code>Infinity</code>'', and * ``<code>-Infinity</code>''. */ static VALUE flo_to_s(flt) VALUE flt; { char buf[32]; double value = RFLOAT(flt)->value; char *p, *e; if (isinf(value)) return rb_str_new2(value < 0 ? "-Infinity" : "Infinity"); else if(isnan(value)) return rb_str_new2("NaN"); sprintf(buf, "%#.15g", value); /* ensure to print decimal point */ if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */ sprintf(buf, "%#.14e", value); if (!(e = strchr(buf, 'e'))) { e = buf + strlen(buf); } } p = e; while (p[-1]=='0' && ISDIGIT(p[-2])) p--; memmove(p, e, strlen(e)+1); return rb_str_new2(buf); }
Returns flt truncated to an Integer.
/* * call-seq: * flt.to_i => integer * flt.to_int => integer * flt.truncate => integer * * Returns <i>flt</i> truncated to an <code>Integer</code>. */ static VALUE flo_truncate(num) VALUE num; { double f = RFLOAT(num)->value; long val; if (f > 0.0) f = floor(f); if (f < 0.0) f = ceil(f); if (!FIXABLE(f)) { return rb_dbl2big(f); } val = f; return LONG2FIX(val); }