Class: Numeric
Overview
Numeric is the class from which all higher-level numeric classes should inherit.
Numeric allows instantiation of heap-allocated objects. Other core numeric classes such as Integer are implemented as immediates, which means that each Integer is a single immutable object which is always passed by value.
a = 1
1.object_id == a.object_id #=> true
There can only ever be one instance of the integer 1
, for example. Ruby ensures this by preventing instantiation. If duplication is attempted, the same instance is returned.
Integer.new(1) #=> NoMethodError: undefined method `new' for Integer:Class
1.dup #=> 1
1.object_id == 1.dup.object_id #=> true
For this reason, Numeric should be used when defining other numeric classes.
Classes which inherit from Numeric must implement coerce
, which returns a two-member Array containing an object that has been coerced into an instance of the new class and self
(see #coerce).
Inheriting classes should also implement arithmetic operator methods (+
, -
, *
and /
) and the <=>
operator (see Comparable). These methods may rely on coerce
to ensure interoperability with instances of other numeric classes.
class Tally < Numeric
def initialize(string)
@string = string
end
def to_s
@string
end
def to_i
@string.size
end
def coerce(other)
[self.class.new('|' * other.to_i), self]
end
def <=>(other)
to_i <=> other.to_i
end
def +(other)
self.class.new('|' * (to_i + other.to_i))
end
def -(other)
self.class.new('|' * (to_i - other.to_i))
end
def *(other)
self.class.new('|' * (to_i * other.to_i))
end
def /(other)
self.class.new('|' * (to_i / other.to_i))
end
end
tally = Tally.new('||')
puts tally * 2 #=> "||||"
puts tally > 1 #=> true
Instance Method Summary collapse
-
#modulo(numeric) ⇒ Object
x.modulo(y)
meansx-y*(x/y).floor
. -
#+ ⇒ Numeric
Unary Plus—Returns the receiver.
-
#- ⇒ Numeric
Unary Minus—Returns the receiver, negated.
-
#<=>(other) ⇒ 0?
Returns zero if
number
equalsother
, otherwise returnsnil
. -
#abs ⇒ Object
Returns the absolute value of
num
. -
#abs2 ⇒ Object
Returns square of self.
-
#angle ⇒ Object
Returns 0 if the value is positive, pi otherwise.
-
#arg ⇒ Object
Returns 0 if the value is positive, pi otherwise.
-
#ceil([ndigits]) ⇒ Integer, Float
Returns the smallest number greater than or equal to
num
with a precision ofndigits
decimal digits (default: 0). -
#clone(freeze: true) ⇒ Numeric
Returns the receiver.
-
#coerce(numeric) ⇒ Array
If
numeric
is the same type asnum
, returns an array[numeric, num]
. -
#conj ⇒ Object
Returns self.
-
#conjugate ⇒ Object
Returns self.
-
#denominator ⇒ Integer
Returns the denominator (always positive).
-
#div(numeric) ⇒ Integer
Uses
/
to perform division, then converts the result to an integer. -
#divmod(numeric) ⇒ Array
Returns an array containing the quotient and modulus obtained by dividing
num
bynumeric
. -
#dup ⇒ Numeric
Returns the receiver.
-
#eql?(numeric) ⇒ Boolean
Returns
true
ifnum
andnumeric
are the same type and have equal values. -
#fdiv(numeric) ⇒ Float
Returns float division.
-
#finite? ⇒ Boolean
Returns
true
ifnum
is a finite number, otherwise returnsfalse
. -
#floor([ndigits]) ⇒ Integer, Float
Returns the largest number less than or equal to
num
with a precision ofndigits
decimal digits (default: 0). -
#i ⇒ Complex(0]
Returns the corresponding imaginary number.
-
#imag ⇒ Object
Returns zero.
-
#imaginary ⇒ Object
Returns zero.
-
#infinite? ⇒ -1, ...
Returns
nil
, -1, or 1 depending on whether the value is finite,-Infinity
, or+Infinity
. -
#integer? ⇒ Boolean
Returns
true
ifnum
is an Integer. -
#magnitude ⇒ Object
Returns the absolute value of
num
. -
#modulo(numeric) ⇒ Object
x.modulo(y)
meansx-y*(x/y).floor
. -
#negative? ⇒ Boolean
Returns
true
ifnum
is less than 0. -
#nonzero? ⇒ self?
Returns
self
ifnum
is not zero,nil
otherwise. -
#numerator ⇒ Integer
Returns the numerator.
-
#phase ⇒ Object
Returns 0 if the value is positive, pi otherwise.
-
#polar ⇒ Array
Returns an array; [num.abs, num.arg].
-
#positive? ⇒ Boolean
Returns
true
ifnum
is greater than 0. -
#quo(y) ⇒ Object
Returns the most exact division (rational for integers, float for floats).
-
#real ⇒ self
Returns self.
-
#real? ⇒ Boolean
Returns
true
ifnum
is a real number (i.e. not Complex). -
#rect ⇒ Object
Returns an array; [num, 0].
-
#rectangular ⇒ Object
Returns an array; [num, 0].
-
#remainder(numeric) ⇒ Object
x.remainder(y)
meansx-y*(x/y).truncate
. -
#round([ndigits]) ⇒ Integer, Float
Returns
num
rounded to the nearest value with a precision ofndigits
decimal digits (default: 0). -
#singleton_method_added(name) ⇒ Object
:nodoc:.
-
#step(*args) ⇒ Object
Invokes the given block with the sequence of numbers starting at
num
, incremented bystep
(defaulted to1
) on each call. -
#to_c ⇒ Object
Returns the value as a complex.
-
#to_int ⇒ Integer
Invokes the child class’s
to_i
method to convertnum
to an integer. -
#truncate([ndigits]) ⇒ Integer, Float
Returns
num
truncated (toward zero) to a precision ofndigits
decimal digits (default: 0). -
#zero? ⇒ Boolean
Returns
true
ifnum
has a zero value.
Methods included from Comparable
#<, #<=, #==, #>, #>=, #between?, #clamp
Instance Method Details
#modulo(numeric) ⇒ Object
x.modulo(y)
means x-y*(x/y).floor
.
Equivalent to num.divmod(numeric)[1]
.
See Numeric#divmod.
632 633 634 635 636 637 638 |
# File 'numeric.c', line 632
static VALUE
num_modulo(VALUE x, VALUE y)
{
VALUE q = num_funcall1(x, id_div, y);
return rb_funcall(x, '-', 1,
rb_funcall(y, '*', 1, q));
}
|
#+ ⇒ Numeric
Unary Plus—Returns the receiver.
548 549 550 551 552 |
# File 'numeric.c', line 548
static VALUE
num_uplus(VALUE num)
{
return num;
}
|
#- ⇒ Numeric
Unary Minus—Returns the receiver, negated.
578 579 580 581 582 583 584 585 586 587 |
# File 'numeric.c', line 578
static VALUE
num_uminus(VALUE num)
{
VALUE zero;
zero = INT2FIX(0);
do_coerce(&zero, &num, TRUE);
return num_funcall1(zero, '-', num);
}
|
#<=>(other) ⇒ 0?
Returns zero if number
equals other
, otherwise returns nil
.
1366 1367 1368 1369 1370 1371 |
# File 'numeric.c', line 1366
static VALUE
num_cmp(VALUE x, VALUE y)
{
if (x == y) return INT2FIX(0);
return Qnil;
}
|
#abs ⇒ Numeric #magnitude ⇒ Numeric
Returns the absolute value of num
.
12.abs #=> 12
(-34.56).abs #=> 34.56
-34.56.abs #=> 34.56
Numeric#magnitude is an alias for Numeric#abs.
756 757 758 759 760 761 762 763 |
# File 'numeric.c', line 756
static VALUE
num_abs(VALUE num)
{
if (rb_num_negative_int_p(num)) {
return num_funcall0(num, idUMinus);
}
return num;
}
|
#abs2 ⇒ Object
Returns square of self.
2185 2186 2187 2188 2189 |
# File 'complex.c', line 2185
static VALUE
numeric_abs2(VALUE self)
{
return f_mul(self, self);
}
|
#arg ⇒ 0, Float #angle ⇒ 0, Float #phase ⇒ 0, Float
Returns 0 if the value is positive, pi otherwise.
2199 2200 2201 2202 2203 2204 2205 |
# File 'complex.c', line 2199
static VALUE
numeric_arg(VALUE self)
{
if (f_positive_p(self))
return INT2FIX(0);
return DBL2NUM(M_PI);
}
|
#arg ⇒ 0, Float #angle ⇒ 0, Float #phase ⇒ 0, Float
Returns 0 if the value is positive, pi otherwise.
2199 2200 2201 2202 2203 2204 2205 |
# File 'complex.c', line 2199
static VALUE
numeric_arg(VALUE self)
{
if (f_positive_p(self))
return INT2FIX(0);
return DBL2NUM(M_PI);
}
|
#ceil([ndigits]) ⇒ Integer, Float
Returns the smallest number greater than or equal to num
with a precision of ndigits
decimal digits (default: 0).
Numeric implements this by converting its value to a Float and invoking Float#ceil.
2468 2469 2470 2471 2472 |
# File 'numeric.c', line 2468
static VALUE
num_ceil(int argc, VALUE *argv, VALUE num)
{
return flo_ceil(argc, argv, rb_Float(num));
}
|
#clone(freeze: true) ⇒ Numeric
Returns the receiver. freeze
cannot be false
.
516 517 518 519 520 |
# File 'numeric.c', line 516
static VALUE
num_clone(int argc, VALUE *argv, VALUE x)
{
return rb_immutable_obj_clone(argc, argv, x);
}
|
#coerce(numeric) ⇒ Array
If numeric
is the same type as num
, returns an array [numeric, num]
. Otherwise, returns an array with both numeric
and num
represented as Float objects.
This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator.
1.coerce(2.5) #=> [2.5, 1.0]
1.2.coerce(3) #=> [3.0, 1.2]
1.coerce(2) #=> [2, 1]
413 414 415 416 417 418 419 420 421 |
# File 'numeric.c', line 413
static VALUE
num_coerce(VALUE x, VALUE y)
{
if (CLASS_OF(x) == CLASS_OF(y))
return rb_assoc_new(y, x);
x = rb_Float(x);
y = rb_Float(y);
return rb_assoc_new(y, x);
}
|
#conj ⇒ self #conjugate ⇒ self
Returns self.
2259 2260 2261 2262 2263 |
# File 'complex.c', line 2259
static VALUE
numeric_conj(VALUE self)
{
return self;
}
|
#conj ⇒ self #conjugate ⇒ self
Returns self.
2259 2260 2261 2262 2263 |
# File 'complex.c', line 2259
static VALUE
numeric_conj(VALUE self)
{
return self;
}
|
#denominator ⇒ Integer
Returns the denominator (always positive).
2007 2008 2009 2010 2011 |
# File 'rational.c', line 2007
static VALUE
numeric_denominator(VALUE self)
{
return f_denominator(f_to_r(self));
}
|
#div(numeric) ⇒ Integer
Uses /
to perform division, then converts the result to an integer. Numeric does not define the /
operator; this is left to subclasses.
Equivalent to num.divmod(numeric)[0]
.
See Numeric#divmod.
614 615 616 617 618 619 |
# File 'numeric.c', line 614
static VALUE
num_div(VALUE x, VALUE y)
{
if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0);
}
|
#divmod(numeric) ⇒ Array
Returns an array containing the quotient and modulus obtained by dividing num
by numeric
.
If q, r = x.divmod(y)
, then
q = floor(x/y)
x = q*y + r
The quotient is rounded toward negative infinity, as shown in the following table:
a | b | a.divmod(b) | a/b | a.modulo(b) | a.remainder(b)
------+-----+---------------+---------+-------------+---------------
13 | 4 | 3, 1 | 3 | 1 | 1
------+-----+---------------+---------+-------------+---------------
13 | -4 | -4, -3 | -4 | -3 | 1
------+-----+---------------+---------+-------------+---------------
-13 | 4 | -4, 3 | -4 | 3 | -1
------+-----+---------------+---------+-------------+---------------
-13 | -4 | 3, -1 | 3 | -1 | -1
------+-----+---------------+---------+-------------+---------------
11.5 | 4 | 2, 3.5 | 2.875 | 3.5 | 3.5
------+-----+---------------+---------+-------------+---------------
11.5 | -4 | -3, -0.5 | -2.875 | -0.5 | 3.5
------+-----+---------------+---------+-------------+---------------
-11.5 | 4 | -3, 0.5 | -2.875 | 0.5 | -3.5
------+-----+---------------+---------+-------------+---------------
-11.5 | -4 | 2, -3.5 | 2.875 | -3.5 | -3.5
Examples
11.divmod(3) #=> [3, 2]
11.divmod(-3) #=> [-4, -1]
11.divmod(3.5) #=> [3, 0.5]
(-11).divmod(3.5) #=> [-4, 3.0]
11.5.divmod(3.5) #=> [3, 1.0]
707 708 709 710 711 |
# File 'numeric.c', line 707
static VALUE
num_divmod(VALUE x, VALUE y)
{
return rb_assoc_new(num_div(x, y), num_modulo(x, y));
}
|
#dup ⇒ Numeric
Returns the receiver.
532 533 534 535 536 |
# File 'numeric.c', line 532
static VALUE
num_dup(VALUE x)
{
return x;
}
|
#eql?(numeric) ⇒ Boolean
Returns true
if num
and numeric
are the same type and have equal values. Contrast this with Numeric#==, which performs type conversions.
1 == 1.0 #=> true
1.eql?(1.0) #=> false
1.0.eql?(1.0) #=> true
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
# File 'numeric.c', line 1347
static VALUE
num_eql(VALUE x, VALUE y)
{
if (TYPE(x) != TYPE(y)) return Qfalse;
if (RB_TYPE_P(x, T_BIGNUM)) {
return rb_big_eql(x, y);
}
return rb_equal(x, y);
}
|
#fdiv(numeric) ⇒ Float
Returns float division.
596 597 598 599 600 |
# File 'numeric.c', line 596
static VALUE
num_fdiv(VALUE x, VALUE y)
{
return rb_funcall(rb_Float(x), '/', 1, y);
}
|
#finite? ⇒ Boolean
Returns true
if num
is a finite number, otherwise returns false
.
820 821 822 823 824 |
# File 'numeric.c', line 820
static VALUE
num_finite_p(VALUE num)
{
return Qtrue;
}
|
#floor([ndigits]) ⇒ Integer, Float
Returns the largest number less than or equal to num
with a precision of ndigits
decimal digits (default: 0).
Numeric implements this by converting its value to a Float and invoking Float#floor.
2451 2452 2453 2454 2455 |
# File 'numeric.c', line 2451
static VALUE
num_floor(int argc, VALUE *argv, VALUE num)
{
return flo_floor(argc, argv, rb_Float(num));
}
|
#i ⇒ Complex(0]
Returns the corresponding imaginary number. Not available for complex numbers.
-42.i #=> (0-42i)
2.0.i #=> (0+2.0i)
565 566 567 568 569 |
# File 'numeric.c', line 565
static VALUE
num_imaginary(VALUE num)
{
return rb_complex_new(INT2FIX(0), num);
}
|
#imag ⇒ 0 #imaginary ⇒ 0
Returns zero.
2173 2174 2175 2176 2177 |
# File 'complex.c', line 2173
static VALUE
numeric_imag(VALUE self)
{
return INT2FIX(0);
}
|
#imag ⇒ 0 #imaginary ⇒ 0
Returns zero.
2173 2174 2175 2176 2177 |
# File 'complex.c', line 2173
static VALUE
numeric_imag(VALUE self)
{
return INT2FIX(0);
}
|
#infinite? ⇒ -1, ...
Returns nil
, -1, or 1 depending on whether the value is finite, -Infinity
, or +Infinity
.
833 834 835 836 837 |
# File 'numeric.c', line 833
static VALUE
num_infinite_p(VALUE num)
{
return Qnil;
}
|
#integer? ⇒ Boolean
Returns true
if num
is an Integer.
1.0.integer? #=> false
1.integer? #=> true
736 737 738 739 740 |
# File 'numeric.c', line 736
static VALUE
num_int_p(VALUE num)
{
return Qfalse;
}
|
#abs ⇒ Numeric #magnitude ⇒ Numeric
Returns the absolute value of num
.
12.abs #=> 12
(-34.56).abs #=> 34.56
-34.56.abs #=> 34.56
Numeric#magnitude is an alias for Numeric#abs.
756 757 758 759 760 761 762 763 |
# File 'numeric.c', line 756
static VALUE
num_abs(VALUE num)
{
if (rb_num_negative_int_p(num)) {
return num_funcall0(num, idUMinus);
}
return num;
}
|
#modulo(numeric) ⇒ Object
x.modulo(y)
means x-y*(x/y).floor
.
Equivalent to num.divmod(numeric)[1]
.
See Numeric#divmod.
632 633 634 635 636 637 638 |
# File 'numeric.c', line 632
static VALUE
num_modulo(VALUE x, VALUE y)
{
VALUE q = num_funcall1(x, id_div, y);
return rb_funcall(x, '-', 1,
rb_funcall(y, '*', 1, q));
}
|
#negative? ⇒ Boolean
Returns true
if num
is less than 0.
886 887 888 889 890 |
# File 'numeric.c', line 886
static VALUE
num_negative_p(VALUE num)
{
return rb_num_negative_int_p(num) ? Qtrue : Qfalse;
}
|
#nonzero? ⇒ self?
Returns self
if num
is not zero, nil
otherwise.
This behavior is useful when chaining comparisons:
a = %w( z Bb bB bb BB a aA Aa AA A )
b = a.sort {|a,b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
b #=> ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
805 806 807 808 809 810 811 812 |
# File 'numeric.c', line 805
static VALUE
num_nonzero_p(VALUE num)
{
if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
return Qnil;
}
return num;
}
|
#numerator ⇒ Integer
Returns the numerator.
1995 1996 1997 1998 1999 |
# File 'rational.c', line 1995
static VALUE
numeric_numerator(VALUE self)
{
return f_numerator(f_to_r(self));
}
|
#arg ⇒ 0, Float #angle ⇒ 0, Float #phase ⇒ 0, Float
Returns 0 if the value is positive, pi otherwise.
2199 2200 2201 2202 2203 2204 2205 |
# File 'complex.c', line 2199
static VALUE
numeric_arg(VALUE self)
{
if (f_positive_p(self))
return INT2FIX(0);
return DBL2NUM(M_PI);
}
|
#polar ⇒ Array
Returns an array; [num.abs, num.arg].
2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 |
# File 'complex.c', line 2228
static VALUE
numeric_polar(VALUE self)
{
VALUE abs, arg;
if (RB_INTEGER_TYPE_P(self)) {
abs = rb_int_abs(self);
arg = numeric_arg(self);
}
else if (RB_FLOAT_TYPE_P(self)) {
abs = rb_float_abs(self);
arg = float_arg(self);
}
else if (RB_TYPE_P(self, T_RATIONAL)) {
abs = rb_rational_abs(self);
arg = numeric_arg(self);
}
else {
abs = f_abs(self);
arg = f_arg(self);
}
return rb_assoc_new(abs, arg);
}
|
#positive? ⇒ Boolean
Returns true
if num
is greater than 0.
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 |
# File 'numeric.c', line 863
static VALUE
num_positive_p(VALUE num)
{
const ID mid = '>';
if (FIXNUM_P(num)) {
if (method_basic_p(rb_cInteger))
return (SIGNED_VALUE)num > (SIGNED_VALUE)INT2FIX(0) ? Qtrue : Qfalse;
}
else if (RB_TYPE_P(num, T_BIGNUM)) {
if (method_basic_p(rb_cInteger))
return BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num) ? Qtrue : Qfalse;
}
return rb_num_compare_with_zero(num, mid);
}
|
#quo(int_or_rat) ⇒ Object #quo(flo) ⇒ Object
Returns the most exact division (rational for integers, float for floats).
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 |
# File 'rational.c', line 2022
VALUE
rb_numeric_quo(VALUE x, VALUE y)
{
if (RB_TYPE_P(x, T_COMPLEX)) {
return rb_complex_div(x, y);
}
if (RB_FLOAT_TYPE_P(y)) {
return rb_funcallv(x, idFdiv, 1, &y);
}
if (canonicalization) {
x = rb_rational_raw1(x);
}
else {
x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
}
return nurat_div(x, y);
}
|
#real ⇒ self
Returns self.
2160 2161 2162 2163 2164 |
# File 'complex.c', line 2160
static VALUE
numeric_real(VALUE self)
{
return self;
}
|
#real? ⇒ Boolean
Returns true
if num
is a real number (i.e. not Complex).
720 721 722 723 724 |
# File 'numeric.c', line 720
static VALUE
num_real_p(VALUE num)
{
return Qtrue;
}
|
#rect ⇒ Array #rectangular ⇒ Array
Returns an array; [num, 0].
2214 2215 2216 2217 2218 |
# File 'complex.c', line 2214
static VALUE
numeric_rect(VALUE self)
{
return rb_assoc_new(self, INT2FIX(0));
}
|
#rect ⇒ Array #rectangular ⇒ Array
Returns an array; [num, 0].
2214 2215 2216 2217 2218 |
# File 'complex.c', line 2214
static VALUE
numeric_rect(VALUE self)
{
return rb_assoc_new(self, INT2FIX(0));
}
|
#remainder(numeric) ⇒ Object
x.remainder(y)
means x-y*(x/y).truncate
.
See Numeric#divmod.
649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
# File 'numeric.c', line 649
static VALUE
num_remainder(VALUE x, VALUE y)
{
VALUE z = num_funcall1(x, '%', y);
if ((!rb_equal(z, INT2FIX(0))) &&
((rb_num_negative_int_p(x) &&
rb_num_positive_int_p(y)) ||
(rb_num_positive_int_p(x) &&
rb_num_negative_int_p(y)))) {
return rb_funcall(z, '-', 1, y);
}
return z;
}
|
#round([ndigits]) ⇒ Integer, Float
Returns num
rounded to the nearest value with a precision of ndigits
decimal digits (default: 0).
Numeric implements this by converting its value to a Float and invoking Float#round.
2485 2486 2487 2488 2489 |
# File 'numeric.c', line 2485
static VALUE
num_round(int argc, VALUE* argv, VALUE num)
{
return flo_round(argc, argv, rb_Float(num));
}
|
#singleton_method_added(name) ⇒ Object
:nodoc:
Trap attempts to add methods to Numeric objects. Always raises a TypeError.
Numerics should be values; singleton_methods should not be added to them.
495 496 497 498 499 500 501 502 503 504 505 506 507 |
# File 'numeric.c', line 495
static VALUE
num_sadded(VALUE x, VALUE name)
{
ID mid = rb_to_id(name);
/* ruby_frame = ruby_frame->prev; */ /* pop frame for "singleton_method_added" */
rb_remove_method_id(rb_singleton_class(x), mid);
rb_raise(rb_eTypeError,
"can't define singleton method \"%"PRIsVALUE"\" for %"PRIsVALUE,
rb_id2str(mid),
rb_obj_class(x));
UNREACHABLE_RETURN(Qnil);
}
|
#step(by: step, to: limit) {|i| ... } ⇒ self #step(by: step, to: limit) ⇒ Object #step(by: step, to: limit) ⇒ Object #step(limit = nil, step = 1) {|i| ... } ⇒ self #step(limit = nil, step = 1) ⇒ Object #step(limit = nil, step = 1) ⇒ Object
Invokes the given block with the sequence of numbers starting at num
, incremented by step
(defaulted to 1
) on each call.
The loop finishes when the value to be passed to the block is greater than limit
(if step
is positive) or less than limit
(if step
is negative), where limit
is defaulted to infinity.
In the recommended keyword argument style, either or both of step
and limit
(default infinity) can be omitted. In the fixed position argument style, zero as a step (i.e. num.step(limit, 0)
) is not allowed for historical compatibility reasons.
If all the arguments are integers, the loop operates using an integer counter.
If any of the arguments are floating point numbers, all are converted to floats, and the loop is executed floor(n + n*Float::EPSILON) + 1 times, where n = (limit - num)/step.
Otherwise, the loop starts at num
, uses either the less-than (<
) or greater-than (>
) operator to compare the counter against limit
, and increments itself using the +
operator.
If no block is given, an Enumerator is returned instead. Especially, the enumerator is an Enumerator::ArithmeticSequence if both limit
and step
are kind of Numeric or nil
.
For example:
p 1.step.take(4)
p 10.step(by: -1).take(4)
3.step(to: 5) {|i| print i, " " }
1.step(10, 2) {|i| print i, " " }
Math::E.step(to: Math::PI, by: 0.2) {|f| print f, " " }
Will produce:
[1, 2, 3, 4]
[10, 9, 8, 7]
3 4 5
1 3 5 7 9
2.718281828459045 2.9182818284590453 3.118281828459045
2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 |
# File 'numeric.c', line 2764
static VALUE
num_step(int argc, VALUE *argv, VALUE from)
{
VALUE to, step;
int desc, inf;
if (!rb_block_given_p()) {
VALUE by = Qundef;
num_step_extract_args(argc, argv, &to, &step, &by);
if (by != Qundef) {
step = by;
}
if (NIL_P(step)) {
step = INT2FIX(1);
}
if ((NIL_P(to) || rb_obj_is_kind_of(to, rb_cNumeric)) &&
rb_obj_is_kind_of(step, rb_cNumeric)) {
return rb_arith_seq_new(from, ID2SYM(rb_frame_this_func()), argc, argv,
num_step_size, from, to, step, FALSE);
}
return SIZED_ENUMERATOR(from, 2, ((VALUE [2]){to, step}), num_step_size);
}
desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
if (rb_equal(step, INT2FIX(0))) {
inf = 1;
}
else if (RB_TYPE_P(to, T_FLOAT)) {
double f = RFLOAT_VALUE(to);
inf = isinf(f) && (signbit(f) ? desc : !desc);
}
else inf = 0;
if (FIXNUM_P(from) && (inf || FIXNUM_P(to)) && FIXNUM_P(step)) {
long i = FIX2LONG(from);
long diff = FIX2LONG(step);
if (inf) {
for (;; i += diff)
rb_yield(LONG2FIX(i));
}
else {
long end = FIX2LONG(to);
if (desc) {
for (; i >= end; i += diff)
rb_yield(LONG2FIX(i));
}
else {
for (; i <= end; i += diff)
rb_yield(LONG2FIX(i));
}
}
}
else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
VALUE i = from;
if (inf) {
for (;; i = rb_funcall(i, '+', 1, step))
rb_yield(i);
}
else {
ID cmp = desc ? '<' : '>';
for (; !RTEST(rb_funcall(i, cmp, 1, to)); i = rb_funcall(i, '+', 1, step))
rb_yield(i);
}
}
return from;
}
|
#to_c ⇒ Object
Returns the value as a complex.
1707 1708 1709 1710 1711 |
# File 'complex.c', line 1707
static VALUE
numeric_to_c(VALUE self)
{
return rb_complex_new1(self);
}
|
#to_int ⇒ Integer
Invokes the child class’s to_i
method to convert num
to an integer.
1.0.class #=> Float
1.0.to_int.class #=> Integer
1.0.to_i.class #=> Integer
850 851 852 853 854 |
# File 'numeric.c', line 850
static VALUE
num_to_int(VALUE num)
{
return num_funcall0(num, id_to_i);
}
|
#truncate([ndigits]) ⇒ Integer, Float
Returns num
truncated (toward zero) to a precision of ndigits
decimal digits (default: 0).
Numeric implements this by converting its value to a Float and invoking Float#truncate.
2502 2503 2504 2505 2506 |
# File 'numeric.c', line 2502
static VALUE
num_truncate(int argc, VALUE *argv, VALUE num)
{
return flo_truncate(argc, argv, rb_Float(num));
}
|
#zero? ⇒ Boolean
Returns true
if num
has a zero value.
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
# File 'numeric.c', line 772
static VALUE
num_zero_p(VALUE num)
{
if (FIXNUM_P(num)) {
if (FIXNUM_ZERO_P(num)) {
return Qtrue;
}
}
else if (RB_TYPE_P(num, T_BIGNUM)) {
if (rb_bigzero_p(num)) {
/* this should not happen usually */
return Qtrue;
}
}
else if (rb_equal(num, INT2FIX(0))) {
return Qtrue;
}
return Qfalse;
}
|