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
.
1386 1387 1388 1389 1390 1391 |
# File 'numeric.c', line 1386
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.
2184 2185 2186 2187 2188 |
# File 'complex.c', line 2184
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.
2198 2199 2200 2201 2202 2203 2204 |
# File 'complex.c', line 2198
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.
2198 2199 2200 2201 2202 2203 2204 |
# File 'complex.c', line 2198
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.
2496 2497 2498 2499 2500 |
# File 'numeric.c', line 2496
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]
405 406 407 408 409 410 411 412 413 |
# File 'numeric.c', line 405
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.
2258 2259 2260 2261 2262 |
# File 'complex.c', line 2258
static VALUE
numeric_conj(VALUE self)
{
return self;
}
|
#conj ⇒ self #conjugate ⇒ self
Returns self.
2258 2259 2260 2261 2262 |
# File 'complex.c', line 2258
static VALUE
numeric_conj(VALUE self)
{
return self;
}
|
#denominator ⇒ Integer
Returns the denominator (always positive).
2001 2002 2003 2004 2005 |
# File 'rational.c', line 2001
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
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 |
# File 'numeric.c', line 1367
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
.
833 834 835 836 837 |
# File 'numeric.c', line 833
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.
2479 2480 2481 2482 2483 |
# File 'numeric.c', line 2479
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.
2172 2173 2174 2175 2176 |
# File 'complex.c', line 2172
static VALUE
numeric_imag(VALUE self)
{
return INT2FIX(0);
}
|
#imag ⇒ 0 #imaginary ⇒ 0
Returns zero.
2172 2173 2174 2175 2176 |
# File 'complex.c', line 2172
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
.
846 847 848 849 850 |
# File 'numeric.c', line 846
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.
899 900 901 902 903 |
# File 'numeric.c', line 899
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"]
818 819 820 821 822 823 824 825 |
# File 'numeric.c', line 818
static VALUE
num_nonzero_p(VALUE num)
{
if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
return Qnil;
}
return num;
}
|
#numerator ⇒ Integer
Returns the numerator.
1989 1990 1991 1992 1993 |
# File 'rational.c', line 1989
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.
2198 2199 2200 2201 2202 2203 2204 |
# File 'complex.c', line 2198
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].
2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 |
# File 'complex.c', line 2227
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.
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 |
# File 'numeric.c', line 876
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).
2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 |
# File 'rational.c', line 2016
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);
}
x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
return rb_rational_div(x, y);
}
|
#real ⇒ self
Returns self.
2159 2160 2161 2162 2163 |
# File 'complex.c', line 2159
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].
2213 2214 2215 2216 2217 |
# File 'complex.c', line 2213
static VALUE
numeric_rect(VALUE self)
{
return rb_assoc_new(self, INT2FIX(0));
}
|
#rect ⇒ Array #rectangular ⇒ Array
Returns an array; [num, 0].
2213 2214 2215 2216 2217 |
# File 'complex.c', line 2213
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.
2513 2514 2515 2516 2517 |
# File 'numeric.c', line 2513
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
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 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 |
# File 'numeric.c', line 2792
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);
}
else if (rb_equal(step, INT2FIX(0))) {
rb_raise(rb_eArgError, "step can't be 0");
}
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.
1706 1707 1708 1709 1710 |
# File 'complex.c', line 1706
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
863 864 865 866 867 |
# File 'numeric.c', line 863
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.
2530 2531 2532 2533 2534 |
# File 'numeric.c', line 2530
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 |
# File 'numeric.c', line 772
static VALUE
num_zero_p(VALUE num)
{
if (rb_equal(num, INT2FIX(0))) {
return Qtrue;
}
return Qfalse;
}
|