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
What’s Here
First, what’s elsewhere. Class Numeric:
-
Inherits from class Object.
-
Includes module Comparable.
Here, class Numeric provides methods for:
Querying
-
#finite?: Returns true unless
selfis infinite or not a number. -
#infinite?: Returns -1,
nilor 1, depending on whetherselfis-Infinity<tt>, finite, or <tt>Infinity. -
#integer?: Returns whether
selfis an integer. -
#negative?: Returns whether
selfis negative. -
#nonzero?: Returns whether
selfis not zero. -
#positive?: Returns whether
selfis positive. -
#real?: Returns whether
selfis a real value. -
#zero?: Returns whether
selfis zero.
Comparing
-
#<=>: Returns:
-
-1 if
selfis less than the given value. -
0 if
selfis equal to the given value. -
1 if
selfis greater than the given value. -
nilifselfand the given value are not comparable.
-
-
#eql?: Returns whether
selfand the given value have the same value and type.
Converting
-
#% (aliased as #modulo): Returns the remainder of
selfdivided by the given value. -
#-@: Returns the value of
self, negated. -
#abs (aliased as #magnitude): Returns the absolute value of
self. -
#abs2: Returns the square of
self. -
#angle (aliased as #arg and #phase): Returns 0 if
selfis positive, Math::PI otherwise. -
#ceil: Returns the smallest number greater than or equal to
self, to a given precision. -
#coerce: Returns array
[coerced_self, coerced_other]for the given other value. -
#conj (aliased as #conjugate): Returns the complex conjugate of
self. -
#denominator: Returns the denominator (always positive) of the Rational representation of
self. -
#div: Returns the value of
selfdivided by the given value and converted to an integer. -
#divmod: Returns array
[quotient, modulus]resulting from dividingselfthe given divisor. -
#fdiv: Returns the Float result of dividing
selfby the given divisor. -
#floor: Returns the largest number less than or equal to
self, to a given precision. -
#i: Returns the Complex object
Complex(0, self). the given value. -
#imaginary (aliased as #imag): Returns the imaginary part of the
self. -
#numerator: Returns the numerator of the Rational representation of
self; has the same sign asself. -
#polar: Returns the array
[self.abs, self.arg]. -
#quo: Returns the value of
selfdivided by the given value. -
#real: Returns the real part of
self. -
#rect (aliased as #rectangular): Returns the array
[self, 0]. -
#remainder: Returns
self-arg*(self/arg).truncatefor the givenarg. -
#round: Returns the value of
selfrounded to the nearest value for the given a precision. -
#to_c: Returns the Complex representation of
self. -
#to_int: Returns the Integer representation of
self, truncating if necessary. -
#truncate: Returns
selftruncated (toward zero) to a given precision.
Other
-
#clone: Returns
self; does not allow freezing. -
#dup (aliased as #+@): Returns
self. -
#step: Invokes the given block with the sequence of specified numbers.
Instance Method Summary collapse
-
#%(other) ⇒ Object
Returns
selfmodulootheras a real number. -
#- ⇒ Numeric
Unary Minus—Returns the receiver, negated.
-
#<=>(other) ⇒ nil
Returns zero if
selfis the same asother,nilotherwise. -
#abs ⇒ Numeric
Returns the absolute value of
self. -
#abs2 ⇒ Object
Returns the square of
self. -
#arg ⇒ 0, Math::PI
Returns zero if
selfis positive, Math::PI otherwise. -
#arg ⇒ 0, Math::PI
Returns zero if
selfis positive, Math::PI otherwise. -
#ceil(ndigits = 0) ⇒ Float, Integer
Returns the smallest float or integer that is greater than or equal to
self, as specified by the given ‘ndigits`, which must be an integer-convertible object. -
#clone(freeze: true) ⇒ self
Returns
self. -
#coerce(other) ⇒ Array
Returns a 2-element array containing two numeric elements, formed from the two operands
selfandother, of a common compatible type. -
#denominator ⇒ Integer
Returns the denominator (always positive).
-
#div(other) ⇒ Integer
Returns the quotient
self/otheras an integer (viafloor), using method/in the derived class ofself. -
#divmod(other) ⇒ Array
Returns a 2-element array
[q, r], where. -
#eql?(other) ⇒ Boolean
Returns
trueifselfandotherare the same type and have equal values. -
#fdiv(other) ⇒ Float
Returns the quotient
self/otheras a float, using method/in the derived class ofself. -
#floor(ndigits = 0) ⇒ Float, Integer
Returns the largest float or integer that is less than or equal to
self, as specified by the given ‘ndigits`, which must be an integer-convertible object. -
#i ⇒ Object
Returns
Complex(0, self):. -
#abs ⇒ Numeric
Returns the absolute value of
self. -
#%(other) ⇒ Object
Returns
selfmodulootheras a real number. -
#negative? ⇒ Boolean
Returns
trueifselfis less than 0,falseotherwise. -
#nonzero? ⇒ self?
Returns
selfifselfis not a zero value,nilotherwise; uses methodzero?for the evaluation. -
#numerator ⇒ Integer
Returns the numerator.
-
#arg ⇒ 0, Math::PI
Returns zero if
selfis positive, Math::PI otherwise. -
#polar ⇒ Array
Returns array
[self.abs, self.arg]. -
#positive? ⇒ Boolean
Returns
trueifselfis greater than 0,falseotherwise. -
#quo(y) ⇒ Object
Returns the most exact division (rational for integers, float for floats).
-
#rect ⇒ Array
Returns array
[self, 0]. -
#rect ⇒ Array
Returns array
[self, 0]. -
#remainder(other) ⇒ Object
Returns the remainder after dividing
selfbyother. -
#round(digits = 0) ⇒ Integer, Float
Returns
selfrounded to the nearest value with a precision ofdigitsdecimal digits. -
#singleton_method_added(name) ⇒ Object
:nodoc:.
-
#step(*args) ⇒ Object
Generates a sequence of numbers; with a block given, traverses the sequence.
-
#to_c ⇒ Object
Returns
selfas a Complex object. -
#to_int ⇒ Integer
Returns
selfas an integer; converts using methodto_iin the derived class. -
#truncate(digits = 0) ⇒ Integer, Float
Returns
selftruncated (toward zero) to a precision ofdigitsdecimal digits. -
#zero? ⇒ Boolean
Returns
trueifzerohas a zero value,falseotherwise.
Methods included from Comparable
#<, #<=, #==, #>, #>=, #between?, #clamp
Instance Method Details
#%(other) ⇒ Object
Returns self modulo other as a real number.
Of the Core and Standard Library classes, only Rational uses this implementation.
For Rational r and real number n, these expressions are equivalent:
r % n
r-n*(r/n).floor
r.divmod(n)[1]
See Numeric#divmod.
Examples:
r = Rational(1, 2) # => (1/2)
r2 = Rational(2, 3) # => (2/3)
r % r2 # => (1/2)
r % 2 # => (1/2)
r % 2.0 # => 0.5
r = Rational(301,100) # => (301/100)
r2 = Rational(7,5) # => (7/5)
r % r2 # => (21/100)
r % -r2 # => (-119/100)
(-r) % r2 # => (119/100)
(-r) %-r2 # => (-21/100)
666 667 668 669 670 671 672 |
# File 'numeric.c', line 666 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 Minus—Returns the receiver, negated.
582 583 584 585 586 587 588 589 590 591 |
# File 'numeric.c', line 582 static VALUE num_uminus(VALUE num) { VALUE zero; zero = INT2FIX(0); do_coerce(&zero, &num, TRUE); return num_funcall1(zero, '-', num); } |
#<=>(other) ⇒ nil
Returns zero if self is the same as other, nil otherwise.
No subclass in the Ruby Core or Standard Library uses this implementation.
1551 1552 1553 1554 1555 1556 |
# File 'numeric.c', line 1551 static VALUE num_cmp(VALUE x, VALUE y) { if (x == y) return INT2FIX(0); return Qnil; } |
#abs ⇒ Numeric
Returns the absolute value of self.
12.abs #=> 12
(-34.56).abs #=> 34.56
-34.56.abs #=> 34.56
774 775 776 777 778 779 780 781 |
# File 'numeric.c', line 774 static VALUE num_abs(VALUE num) { if (rb_num_negative_int_p(num)) { return num_funcall0(num, idUMinus); } return num; } |
#abs2 ⇒ Object
Returns the square of self.
2385 2386 2387 2388 2389 |
# File 'complex.c', line 2385 static VALUE numeric_abs2(VALUE self) { return f_mul(self, self); } |
#arg ⇒ 0, Math::PI
Returns zero if self is positive, Math::PI otherwise.
2397 2398 2399 2400 2401 2402 2403 |
# File 'complex.c', line 2397 static VALUE numeric_arg(VALUE self) { if (f_positive_p(self)) return INT2FIX(0); return DBL2NUM(M_PI); } |
#arg ⇒ 0, Math::PI
Returns zero if self is positive, Math::PI otherwise.
2397 2398 2399 2400 2401 2402 2403 |
# File 'complex.c', line 2397 static VALUE numeric_arg(VALUE self) { if (f_positive_p(self)) return INT2FIX(0); return DBL2NUM(M_PI); } |
#ceil(ndigits = 0) ⇒ Float, Integer
Returns the smallest float or integer that is greater than or equal to self, as specified by the given ‘ndigits`, which must be an integer-convertible object.
Equivalent to self.to_f.ceil(ndigits).
Related: #floor, Float#ceil.
2740 2741 2742 2743 2744 |
# File 'numeric.c', line 2740 static VALUE num_ceil(int argc, VALUE *argv, VALUE num) { return flo_ceil(argc, argv, rb_Float(num)); } |
#clone(freeze: true) ⇒ self
Returns self.
Raises an exception if the value for freeze is neither true nor nil.
Related: Numeric#dup.
546 547 548 549 550 |
# File 'numeric.c', line 546 static VALUE num_clone(int argc, VALUE *argv, VALUE x) { return rb_immutable_obj_clone(argc, argv, x); } |
#coerce(other) ⇒ Array
Returns a 2-element array containing two numeric elements, formed from the two operands self and other, of a common compatible type.
Of the Core and Standard Library classes, Integer, Rational, and Complex use this implementation.
Examples:
i = 2 # => 2
i.coerce(3) # => [3, 2]
i.coerce(3.0) # => [3.0, 2.0]
i.coerce(Rational(1, 2)) # => [0.5, 2.0]
i.coerce(Complex(3, 4)) # Raises RangeError.
r = Rational(5, 2) # => (5/2)
r.coerce(2) # => [(2/1), (5/2)]
r.coerce(2.0) # => [2.0, 2.5]
r.coerce(Rational(2, 3)) # => [(2/3), (5/2)]
r.coerce(Complex(3, 4)) # => [(3+4i), ((5/2)+0i)]
c = Complex(2, 3) # => (2+3i)
c.coerce(2) # => [(2+0i), (2+3i)]
c.coerce(2.0) # => [(2.0+0i), (2+3i)]
c.coerce(Rational(1, 2)) # => [((1/2)+0i), (2+3i)]
c.coerce(Complex(3, 4)) # => [(3+4i), (2+3i)]
Raises an exception if any type conversion fails.
430 431 432 433 434 435 436 437 438 |
# File 'numeric.c', line 430 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); } |
#denominator ⇒ Integer
Returns the denominator (always positive).
2027 2028 2029 2030 2031 |
# File 'rational.c', line 2027 static VALUE numeric_denominator(VALUE self) { return f_denominator(f_to_r(self)); } |
#div(other) ⇒ Integer
Returns the quotient self/other as an integer (via floor), using method / in the derived class of self. (Numeric itself does not define method /.)
Of the Core and Standard Library classes, Only Float and Rational use this implementation.
625 626 627 628 629 630 |
# File 'numeric.c', line 625 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(other) ⇒ Array
Returns a 2-element array [q, r], where
q = (self/other).floor # Quotient
r = self % other # Remainder
Of the Core and Standard Library classes, only Rational uses this implementation.
Examples:
Rational(11, 1).divmod(4) # => [2, (3/1)]
Rational(11, 1).divmod(-4) # => [-3, (-1/1)]
Rational(-11, 1).divmod(4) # => [-3, (1/1)]
Rational(-11, 1).divmod(-4) # => [2, (-3/1)]
Rational(12, 1).divmod(4) # => [3, (0/1)]
Rational(12, 1).divmod(-4) # => [-3, (0/1)]
Rational(-12, 1).divmod(4) # => [-3, (0/1)]
Rational(-12, 1).divmod(-4) # => [3, (0/1)]
Rational(13, 1).divmod(4.0) # => [3, 1.0]
Rational(13, 1).divmod(Rational(4, 11)) # => [35, (3/11)]
756 757 758 759 760 |
# File 'numeric.c', line 756 static VALUE num_divmod(VALUE x, VALUE y) { return rb_assoc_new(num_div(x, y), num_modulo(x, y)); } |
#eql?(other) ⇒ Boolean
Returns true if self and other are the same type and have equal values.
Of the Core and Standard Library classes, only Integer, Rational, and Complex use this implementation.
Examples:
1.eql?(1) # => true
1.eql?(1.0) # => false
1.eql?(Rational(1, 1)) # => false
1.eql?(Complex(1, 0)) # => false
Method eql? is different from == in that eql? requires matching types, while == does not.
1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 |
# File 'numeric.c', line 1529 static VALUE num_eql(VALUE x, VALUE y) { if (TYPE(x) != TYPE(y)) return Qfalse; if (RB_BIGNUM_TYPE_P(x)) { return rb_big_eql(x, y); } return rb_equal(x, y); } |
#fdiv(other) ⇒ Float
Returns the quotient self/other as a float, using method / in the derived class of self. (Numeric itself does not define method /.)
Of the Core and Standard Library classes, only BigDecimal uses this implementation.
606 607 608 609 610 |
# File 'numeric.c', line 606 static VALUE num_fdiv(VALUE x, VALUE y) { return rb_funcall(rb_Float(x), '/', 1, y); } |
#floor(ndigits = 0) ⇒ Float, Integer
Returns the largest float or integer that is less than or equal to self, as specified by the given ‘ndigits`, which must be an integer-convertible object.
Equivalent to self.to_f.floor(ndigits).
Related: #ceil, Float#floor.
2720 2721 2722 2723 2724 |
# File 'numeric.c', line 2720 static VALUE num_floor(int argc, VALUE *argv, VALUE num) { return flo_floor(argc, argv, rb_Float(num)); } |
#i ⇒ Object
Returns Complex(0, self):
2.i # => (0+2i)
-2.i # => (0-2i)
2.0.i # => (0+2.0i)
Rational(1, 2).i # => (0+(1/2)*i)
Complex(3, 4).i # Raises NoMethodError.
569 570 571 572 573 |
# File 'numeric.c', line 569 static VALUE num_imaginary(VALUE num) { return rb_complex_new(INT2FIX(0), num); } |
#abs ⇒ Numeric
Returns the absolute value of self.
12.abs #=> 12
(-34.56).abs #=> 34.56
-34.56.abs #=> 34.56
774 775 776 777 778 779 780 781 |
# File 'numeric.c', line 774 static VALUE num_abs(VALUE num) { if (rb_num_negative_int_p(num)) { return num_funcall0(num, idUMinus); } return num; } |
#%(other) ⇒ Object
Returns self modulo other as a real number.
Of the Core and Standard Library classes, only Rational uses this implementation.
For Rational r and real number n, these expressions are equivalent:
r % n
r-n*(r/n).floor
r.divmod(n)[1]
See Numeric#divmod.
Examples:
r = Rational(1, 2) # => (1/2)
r2 = Rational(2, 3) # => (2/3)
r % r2 # => (1/2)
r % 2 # => (1/2)
r % 2.0 # => 0.5
r = Rational(301,100) # => (301/100)
r2 = Rational(7,5) # => (7/5)
r % r2 # => (21/100)
r % -r2 # => (-119/100)
(-r) % r2 # => (119/100)
(-r) %-r2 # => (-21/100)
666 667 668 669 670 671 672 |
# File 'numeric.c', line 666 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 self is less than 0, false otherwise.
902 903 904 905 906 |
# File 'numeric.c', line 902 static VALUE num_negative_p(VALUE num) { return RBOOL(rb_num_negative_int_p(num)); } |
#nonzero? ⇒ self?
Returns self if self is not a zero value, nil otherwise; uses method zero? for the evaluation.
The returned self allows the method to be chained:
a = %w[z Bb bB bb BB a aA Aa AA A]
a.sort {|a, b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
# => ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]
Of the Core and Standard Library classes, Integer, Float, Rational, and Complex use this implementation.
Related: #zero?
836 837 838 839 840 841 842 843 |
# File 'numeric.c', line 836 static VALUE num_nonzero_p(VALUE num) { if (RTEST(num_funcall0(num, rb_intern("zero?")))) { return Qnil; } return num; } |
#numerator ⇒ Integer
Returns the numerator.
2015 2016 2017 2018 2019 |
# File 'rational.c', line 2015 static VALUE numeric_numerator(VALUE self) { return f_numerator(f_to_r(self)); } |
#arg ⇒ 0, Math::PI
Returns zero if self is positive, Math::PI otherwise.
2397 2398 2399 2400 2401 2402 2403 |
# File 'complex.c', line 2397 static VALUE numeric_arg(VALUE self) { if (f_positive_p(self)) return INT2FIX(0); return DBL2NUM(M_PI); } |
#polar ⇒ Array
Returns array [self.abs, self.arg].
2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 |
# File 'complex.c', line 2423 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 self is greater than 0, false otherwise.
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 |
# File 'numeric.c', line 878 static VALUE num_positive_p(VALUE num) { const ID mid = '>'; if (FIXNUM_P(num)) { if (method_basic_p(rb_cInteger)) return RBOOL((SIGNED_VALUE)num > (SIGNED_VALUE)INT2FIX(0)); } else if (RB_BIGNUM_TYPE_P(num)) { if (method_basic_p(rb_cInteger)) return RBOOL(BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num)); } 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).
2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 |
# File 'rational.c', line 2042 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); } |
#rect ⇒ Array
Returns array [self, 0].
2411 2412 2413 2414 2415 |
# File 'complex.c', line 2411 static VALUE numeric_rect(VALUE self) { return rb_assoc_new(self, INT2FIX(0)); } |
#rect ⇒ Array
Returns array [self, 0].
2411 2412 2413 2414 2415 |
# File 'complex.c', line 2411 static VALUE numeric_rect(VALUE self) { return rb_assoc_new(self, INT2FIX(0)); } |
#remainder(other) ⇒ Object
Returns the remainder after dividing self by other.
Of the Core and Standard Library classes, only Float and Rational use this implementation.
Examples:
11.0.remainder(4) # => 3.0
11.0.remainder(-4) # => 3.0
-11.0.remainder(4) # => -3.0
-11.0.remainder(-4) # => -3.0
12.0.remainder(4) # => 0.0
12.0.remainder(-4) # => 0.0
-12.0.remainder(4) # => -0.0
-12.0.remainder(-4) # => -0.0
13.0.remainder(4.0) # => 1.0
13.0.remainder(Rational(4, 1)) # => 1.0
Rational(13, 1).remainder(4) # => (1/1)
Rational(13, 1).remainder(-4) # => (1/1)
Rational(-13, 1).remainder(4) # => (-1/1)
Rational(-13, 1).remainder(-4) # => (-1/1)
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 |
# File 'numeric.c', line 705 static VALUE num_remainder(VALUE x, VALUE y) { if (!rb_obj_is_kind_of(y, rb_cNumeric)) { do_coerce(&x, &y, TRUE); } 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)))) { if (RB_FLOAT_TYPE_P(y)) { if (isinf(RFLOAT_VALUE(y))) { return x; } } return rb_funcall(z, '-', 1, y); } return z; } |
#round(digits = 0) ⇒ Integer, Float
Returns self rounded to the nearest value with a precision of digits decimal digits.
Numeric implements this by converting self to a Float and invoking Float#round.
2757 2758 2759 2760 2761 |
# File 'numeric.c', line 2757 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.
520 521 522 523 524 525 526 527 528 529 530 531 532 |
# File 'numeric.c', line 520 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(to = nil, by = 1) {|n| ... } ⇒ self #step(to = nil, by = 1) ⇒ Object #step(to = nil, by: 1) {|n| ... } ⇒ self #step(to = nil, by: 1) ⇒ Object #step(by: 1, to: ) {|n| ... } ⇒ self #step(by: 1, to: ) ⇒ Object #step(by: , to: nil) {|n| ... } ⇒ self #step(by: , to: nil) ⇒ Object
Generates a sequence of numbers; with a block given, traverses the sequence.
Of the Core and Standard Library classes, Integer, Float, and Rational use this implementation.
A quick example:
squares = []
1.step(by: 2, to: 10) {|i| squares.push(i*i) }
squares # => [1, 9, 25, 49, 81]
The generated sequence:
-
Begins with
self. -
Continues at intervals of
by(which may not be zero). -
Ends with the last number that is within or equal to
to;
that is, less than or equal to +to+ if +by+ is positive,
greater than or equal to +to+ if +by+ is negative.
If +to+ is +nil+, the sequence is of infinite length.
If a block is given, calls the block with each number in the sequence; returns self. If no block is given, returns an Enumerator::ArithmeticSequence.
Keyword Arguments
With keyword arguments by and to, their values (or defaults) determine the step and limit:
# Both keywords given.
squares = []
4.step(by: 2, to: 10) {|i| squares.push(i*i) } # => 4
squares # => [16, 36, 64, 100]
cubes = []
3.step(by: -1.5, to: -3) {|i| cubes.push(i*i*i) } # => 3
cubes # => [27.0, 3.375, 0.0, -3.375, -27.0]
squares = []
1.2.step(by: 0.2, to: 2.0) {|f| squares.push(f*f) }
squares # => [1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0]
squares = []
Rational(6/5).step(by: 0.2, to: 2.0) {|r| squares.push(r*r) }
squares # => [1.0, 1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0]
# Only keyword to given.
squares = []
4.step(to: 10) {|i| squares.push(i*i) } # => 4
squares # => [16, 25, 36, 49, 64, 81, 100]
# Only by given.
# Only keyword by given
squares = []
4.step(by:2) {|i| squares.push(i*i); break if i > 10 }
squares # => [16, 36, 64, 100, 144]
# No block given.
e = 3.step(by: -1.5, to: -3) # => (3.step(by: -1.5, to: -3))
e.class # => Enumerator::ArithmeticSequence
Positional Arguments
With optional positional arguments to and by, their values (or defaults) determine the step and limit:
squares = []
4.step(10, 2) {|i| squares.push(i*i) } # => 4
squares # => [16, 36, 64, 100]
squares = []
4.step(10) {|i| squares.push(i*i) }
squares # => [16, 25, 36, 49, 64, 81, 100]
squares = []
4.step {|i| squares.push(i*i); break if i > 10 } # => nil
squares # => [16, 25, 36, 49, 64, 81, 100, 121]
Implementation Notes
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 - self)/step.
3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 |
# File 'numeric.c', line 3094 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 (!UNDEF_P(by)) { 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_KW(from, 2, ((VALUE [2]){to, step}), num_step_size, FALSE); } desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE); if (rb_equal(step, INT2FIX(0))) { inf = 1; } else if (RB_FLOAT_TYPE_P(to)) { 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 self as a Complex object.
1948 1949 1950 1951 1952 |
# File 'complex.c', line 1948 static VALUE numeric_to_c(VALUE self) { return rb_complex_new1(self); } |
#to_int ⇒ Integer
Returns self as an integer; converts using method to_i in the derived class.
Of the Core and Standard Library classes, only Rational and Complex use this implementation.
Examples:
Rational(1, 2).to_int # => 0
Rational(2, 1).to_int # => 2
Complex(2, 0).to_int # => 2
Complex(2, 1).to_int # Raises RangeError (non-zero imaginary part)
864 865 866 867 868 |
# File 'numeric.c', line 864 static VALUE num_to_int(VALUE num) { return num_funcall0(num, id_to_i); } |
#truncate(digits = 0) ⇒ Integer, Float
Returns self truncated (toward zero) to a precision of digits decimal digits.
Numeric implements this by converting self to a Float and invoking Float#truncate.
2774 2775 2776 2777 2778 |
# File 'numeric.c', line 2774 static VALUE num_truncate(int argc, VALUE *argv, VALUE num) { return flo_truncate(argc, argv, rb_Float(num)); } |
#zero? ⇒ Boolean
Returns true if zero has a zero value, false otherwise.
Of the Core and Standard Library classes, only Rational and Complex use this implementation.
794 795 796 797 798 |
# File 'numeric.c', line 794 static VALUE num_zero_p(VALUE num) { return rb_equal(num, INT2FIX(0)); } |