# class Numeric

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

- Comparing

- Converting

- Other

### Querying¶ ↑

- `finite?`: Returns true unless `self` is infinite or not a number.

- `infinite?`: Returns -1, `nil` or +1, depending on whether `self` 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` if `self` 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 dividing `self` 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 as `self`.

- `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 given `arg`.

- `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.

### Public Instance Methods

self % other → real_numeric
Source

    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));
    }

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)

Also aliased as: modulo
+self → self
Source

    # File numeric.rb, line 89
    def +@
      self
    end

Returns `self`.

-self → numeric
Source

    static VALUE
    num_uminus(VALUE num)
    {
        VALUE zero;

        zero = INT2FIX(0);
        do_coerce(&zero, &num, TRUE);

        return num_funcall1(zero, '-', num);
    }

Unary Minus—Returns the receiver, negated.

self <=> other → zero or nil
Source

    static VALUE
    num_cmp(VALUE x, VALUE y)
    {
        if (x == y) return INT2FIX(0);
        return Qnil;
    }

Returns zero if `self` is the same as `other`, `nil` otherwise.

No subclass in the Ruby Core or Standard Library uses this implementation.

abs → numeric
Source

    static VALUE
    num_abs(VALUE num)
    {
        if (rb_num_negative_int_p(num)) {
            return num_funcall0(num, idUMinus);
        }
        return num;
    }

Returns the absolute value of `self`.

    12.abs        #=> 12
    (-34.56).abs  #=> 34.56
    -34.56.abs    #=> 34.56

Also aliased as: magnitude
abs2 → real
Source

    static VALUE
    numeric_abs2(VALUE self)
    {
        return f_mul(self, self);
    }

Returns the square of `self`.

angle
Alias for: arg
arg → 0 or Math::PI
Source

    static VALUE
    numeric_arg(VALUE self)
    {
        if (f_positive_p(self))
            return INT2FIX(0);
        return DBL2NUM(M_PI);
    }

Returns zero if `self` is positive, Math::PI otherwise.

Also aliased as: angle, phase
ceil(ndigits = 0) → float or integer
Source

    static VALUE
    num_ceil(int argc, VALUE *argv, VALUE num)
    {
        return flo_ceil(argc, argv, rb_Float(num));
    }

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`.

clone(freeze: true) → self
Source

    static VALUE
    num_clone(int argc, VALUE *argv, VALUE x)
    {
        return rb_immutable_obj_clone(argc, argv, x);
    }

Returns `self`.

Raises an exception if the value for `freeze` is neither `true` nor `nil`.

Related: `Numeric#dup`.

coerce(other) → array
Source

    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);
    }

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.

conj → self
Alias for: conjugate
conjugate
Source
Also aliased as: conj
denominator → integer
Source

    static VALUE
    numeric_denominator(VALUE self)
    {
        return f_denominator(f_to_r(self));
    }

Returns the denominator (always positive).

div(other) → integer
Source

    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);
    }

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.

divmod(other) → array
Source

    static VALUE
    num_divmod(VALUE x, VALUE y)
    {
        return rb_assoc_new(num_div(x, y), num_modulo(x, y));
    }

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)]

dup → self
Source

    # File numeric.rb, line 9
    def dup
      self
    end

Returns `self`.

Related: `Numeric#clone`.

eql?(other) → true or false
Source

    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);
    }

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.

fdiv(other) → float
Source

    static VALUE
    num_fdiv(VALUE x, VALUE y)
    {
        return rb_funcall(rb_Float(x), '/', 1, y);
    }

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.

finite? → true or false
Source

    # File numeric.rb, line 48
    def finite?
      true
    end

Returns `true` if `self` is a finite number, `false` otherwise.

floor(ndigits = 0) → float or integer
Source

    static VALUE
    num_floor(int argc, VALUE *argv, VALUE num)
    {
        return flo_floor(argc, argv, rb_Float(num));
    }

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`.

i → complex
Source

    static VALUE
    num_imaginary(VALUE num)
    {
        return rb_complex_new(INT2FIX(0), num);
    }

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.

imag → 0
Alias for: imaginary
imaginary
Source
Also aliased as: imag
infinite? → -1, 1, or nil
Source

    # File numeric.rb, line 58
    def infinite?
      nil
    end

Returns `nil`, -1, or 1 depending on whether `self` is finite, `-Infinity`, or `+Infinity`.

integer? → true or false
Source

    # File numeric.rb, line 39
    def integer?
      false
    end

Returns `true` if `self` is an `Integer`.

    1.0.integer? # => false
    1.integer?   # => true

magnitude
Alias for: abs
modulo
Alias for: %
negative? → true or false
Source

    static VALUE
    num_negative_p(VALUE num)
    {
        return RBOOL(rb_num_negative_int_p(num));
    }

Returns `true` if `self` is less than 0, `false` otherwise.

nonzero? → self or nil
Source

    static VALUE
    num_nonzero_p(VALUE num)
    {
        if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
            return Qnil;
        }
        return num;
    }

    Returns +self+ if +self+ is not a zero value, +nil+ otherwise;
    uses method <tt>zero?</tt> 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?`

numerator → integer
Source

    static VALUE
    numeric_numerator(VALUE self)
    {
        return f_numerator(f_to_r(self));
    }

Returns the numerator.

phase
Alias for: arg
polar → array
Source

    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);
    }

Returns array `[self.abs, self.arg]`.

positive? → true or false
Source

    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);
    }

Returns `true` if `self` is greater than 0, `false` otherwise.

quo(int_or_rat) → rat
quo(flo) → flo
Source

    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);
    }

Returns the most exact division (rational for integers, float for floats).

real → self
Source

    # File numeric.rb, line 27
    def real
      self
    end

Returns `self`.

real? → true or false
Source

    # File numeric.rb, line 18
    def real?
      true
    end

Returns `true` if `self` is a real number (i.e. not `Complex`).

rect → array

Returns array `[self, 0]`.

Alias for: rectangular
rectangular
Source
Also aliased as: rect
remainder(other) → real_number
Source

    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;
    }

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)

round(digits = 0) → integer or float
Source

    static VALUE
    num_round(int argc, VALUE* argv, VALUE num)
    {
        return flo_round(argc, argv, rb_Float(num));
    }

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`.

step(to = nil, by = 1) {|n| ... } → self
step(to = nil, by = 1) → enumerator
step(to = nil, by: 1) {|n| ... } → self
step(to = nil, by: 1) → enumerator
step(by: 1, to: ) {|n| ... } → self
step(by: 1, to: ) → enumerator
step(by: , to: nil) {|n| ... } → self
step(by: , to: nil) → enumerator
Source

    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;
    }

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.

to_c → complex
Source

    static VALUE
    numeric_to_c(VALUE self)
    {
        return rb_complex_new1(self);
    }

Returns `self` as a `Complex` object.

to_int → integer
Source

    static VALUE
    num_to_int(VALUE num)
    {
        return num_funcall0(num, id_to_i);
    }

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)

truncate(digits = 0) → integer or float
Source

    static VALUE
    num_truncate(int argc, VALUE *argv, VALUE num)
    {
        return flo_truncate(argc, argv, rb_Float(num));
    }

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`.

zero? → true or false
Source

    static VALUE
    num_zero_p(VALUE num)
    {
        return rb_equal(num, INT2FIX(0));
    }

Returns `true` if `zero` has a zero value, `false` otherwise.

Of the Core and Standard Library classes, only `Rational` and `Complex` use this implementation.