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
self
is infinite or not a number. -
#infinite?: Returns -1,
nil
or 1, depending on whetherself
is-Infinity<tt>, finite, or <tt>
Infinity. -
#integer?: Returns whether
self
is an integer. -
#negative?: Returns whether
self
is negative. -
#nonzero?: Returns whether
self
is not zero. -
#positive?: Returns whether
self
is positive. -
#real?: Returns whether
self
is a real value. -
#zero?: Returns whether
self
is zero.
Comparing
-
#<=>: Returns:
-
-1 if
self
is less than the given value. -
0 if
self
is equal to the given value. -
1 if
self
is greater than the given value. -
nil
ifself
and the given value are not comparable.
-
-
#eql?: Returns whether
self
and the given value have the same value and type.
Converting
-
#% (aliased as #modulo): Returns the remainder of
self
divided 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
self
is 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
self
divided by the given value and converted to an integer. -
#divmod: Returns array
[quotient, modulus]
resulting from dividingself
the given divisor. -
#fdiv: Returns the Float result of dividing
self
by 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
self
divided 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).truncate
for the givenarg
. -
#round: Returns the value of
self
rounded 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
self
truncated (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
self
moduloother
as a real number. -
#+ ⇒ self
Returns
self
. -
#- ⇒ Numeric
Unary Minus—Returns the receiver, negated.
-
#<=>(other) ⇒ nil
Returns zero if
self
is the same asother
,nil
otherwise. -
#abs ⇒ Numeric
Returns the absolute value of
self
. -
#abs2 ⇒ Object
Returns the square of
self
. -
#arg ⇒ 0, Math::PI
Returns zero if
self
is positive, Math::PI otherwise. -
#arg ⇒ 0, Math::PI
Returns zero if
self
is positive, Math::PI otherwise. -
#ceil(digits = 0) ⇒ Integer, Float
Returns the smallest number that is greater than or equal to
self
with a precision ofdigits
decimal digits. -
#clone(freeze: true) ⇒ self
Returns
self
. -
#coerce(other) ⇒ Array
Returns a 2-element array containing two numeric elements, formed from the two operands
self
andother
, of a common compatible type. -
#denominator ⇒ Integer
Returns the denominator (always positive).
-
#div(other) ⇒ Integer
Returns the quotient
self/other
as an integer (viafloor
), using method/
in the derived class ofself
. -
#divmod(other) ⇒ Array
Returns a 2-element array
[q, r]
, where. -
#dup ⇒ self
Returns
self
. -
#eql?(other) ⇒ Boolean
Returns
true
ifself
andother
are the same type and have equal values. -
#fdiv(other) ⇒ Float
Returns the quotient
self/other
as a float, using method/
in the derived class ofself
. -
#floor(digits = 0) ⇒ Integer, Float
Returns the largest number that is less than or equal to
self
with a precision ofdigits
decimal digits. -
#i ⇒ Object
Returns
Complex(0, self)
:. -
#abs ⇒ Numeric
Returns the absolute value of
self
. -
#%(other) ⇒ Object
Returns
self
moduloother
as a real number. -
#negative? ⇒ Boolean
Returns
true
ifself
is less than 0,false
otherwise. -
#nonzero? ⇒ self?
Returns
self
ifself
is not a zero value,nil
otherwise; uses methodzero?
for the evaluation. -
#numerator ⇒ Integer
Returns the numerator.
-
#arg ⇒ 0, Math::PI
Returns zero if
self
is positive, Math::PI otherwise. -
#polar ⇒ Array
Returns array
[self.abs, self.arg]
. -
#positive? ⇒ Boolean
Returns
true
ifself
is greater than 0,false
otherwise. -
#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
self
byother
. -
#round(digits = 0) ⇒ Integer, Float
Returns
self
rounded to the nearest value with a precision ofdigits
decimal 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
self
as a Complex object. -
#to_int ⇒ Integer
Returns
self
as an integer; converts using methodto_i
in the derived class. -
#truncate(digits = 0) ⇒ Integer, Float
Returns
self
truncated (toward zero) to a precision ofdigits
decimal digits. -
#zero? ⇒ Boolean
Returns
true
ifzero
has a zero value,false
otherwise.
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)
699 700 701 702 703 704 705 |
# File 'numeric.c', line 699
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));
}
|
#+ ⇒ self
Returns self
.
582 583 584 585 586 |
# File 'numeric.c', line 582
static VALUE
num_uplus(VALUE num)
{
return num;
}
|
#- ⇒ Numeric
Unary Minus—Returns the receiver, negated.
615 616 617 618 619 620 621 622 623 624 |
# File 'numeric.c', line 615
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.
1580 1581 1582 1583 1584 1585 |
# File 'numeric.c', line 1580
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
807 808 809 810 811 812 813 814 |
# File 'numeric.c', line 807
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
.
2376 2377 2378 2379 2380 |
# File 'complex.c', line 2376
static VALUE
numeric_abs2(VALUE self)
{
return f_mul(self, self);
}
|
#arg ⇒ 0, Math::PI
Returns zero if self
is positive, Math::PI otherwise.
2388 2389 2390 2391 2392 2393 2394 |
# File 'complex.c', line 2388
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.
2388 2389 2390 2391 2392 2393 2394 |
# File 'complex.c', line 2388
static VALUE
numeric_arg(VALUE self)
{
if (f_positive_p(self))
return INT2FIX(0);
return DBL2NUM(M_PI);
}
|
#ceil(digits = 0) ⇒ Integer, Float
Returns the smallest number that is greater than or equal to self
with a precision of digits
decimal digits.
Numeric implements this by converting self
to a Float and invoking Float#ceil.
2679 2680 2681 2682 2683 |
# File 'numeric.c', line 2679
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).
2022 2023 2024 2025 2026 |
# File 'rational.c', line 2022
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.
658 659 660 661 662 663 |
# File 'numeric.c', line 658
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)]
789 790 791 792 793 |
# File 'numeric.c', line 789
static VALUE
num_divmod(VALUE x, VALUE y)
{
return rb_assoc_new(num_div(x, y), num_modulo(x, y));
}
|
#dup ⇒ self
Returns self
.
Related: Numeric#clone.
565 566 567 568 569 |
# File 'numeric.c', line 565
static VALUE
num_dup(VALUE x)
{
return x;
}
|
#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.
1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 |
# File 'numeric.c', line 1558
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.
639 640 641 642 643 |
# File 'numeric.c', line 639
static VALUE
num_fdiv(VALUE x, VALUE y)
{
return rb_funcall(rb_Float(x), '/', 1, y);
}
|
#floor(digits = 0) ⇒ Integer, Float
Returns the largest number that is less than or equal to self
with a precision of digits
decimal digits.
Numeric implements this by converting self
to a Float and invoking Float#floor.
2662 2663 2664 2665 2666 |
# File 'numeric.c', line 2662
static VALUE
num_floor(int argc, VALUE *argv, VALUE num)
{
return flo_floor(argc, argv, rb_Float(num));
}
|
#i ⇒ Object
602 603 604 605 606 |
# File 'numeric.c', line 602
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
807 808 809 810 811 812 813 814 |
# File 'numeric.c', line 807
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)
699 700 701 702 703 704 705 |
# File 'numeric.c', line 699
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.
933 934 935 936 937 |
# File 'numeric.c', line 933
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.
867 868 869 870 871 872 873 874 |
# File 'numeric.c', line 867
static VALUE
num_nonzero_p(VALUE num)
{
if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
return Qnil;
}
return num;
}
|
#numerator ⇒ Integer
Returns the numerator.
2010 2011 2012 2013 2014 |
# File 'rational.c', line 2010
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.
2388 2389 2390 2391 2392 2393 2394 |
# File 'complex.c', line 2388
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]
.
2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 |
# File 'complex.c', line 2414
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.
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 |
# File 'numeric.c', line 909
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).
2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 |
# File 'rational.c', line 2037
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]
.
2402 2403 2404 2405 2406 |
# File 'complex.c', line 2402
static VALUE
numeric_rect(VALUE self)
{
return rb_assoc_new(self, INT2FIX(0));
}
|
#rect ⇒ Array
Returns array [self, 0]
.
2402 2403 2404 2405 2406 |
# File 'complex.c', line 2402
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)
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
# File 'numeric.c', line 738
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.
2696 2697 2698 2699 2700 |
# File 'numeric.c', line 2696
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 toto
ifby
is positive, greater than or equal toto
ifby
is negative. Ifto
isnil
, 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.
3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 |
# File 'numeric.c', line 3033
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.
1939 1940 1941 1942 1943 |
# File 'complex.c', line 1939
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) # Raises RangeError (non-zero imaginary part)
895 896 897 898 899 |
# File 'numeric.c', line 895
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.
2713 2714 2715 2716 2717 |
# File 'numeric.c', line 2713
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.
827 828 829 830 831 |
# File 'numeric.c', line 827
static VALUE
num_zero_p(VALUE num)
{
return rb_equal(num, INT2FIX(0));
}
|