class Numeric - RDoc Documentation

# 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 click to toggle source

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:

    c % n
    c-n*(c/n).floor
    c.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)

`Numeric#modulo` is an alias for `Numeric#%`.

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

Also aliased as: modulo
+self → self click to toggle source

Returns `self`.

    static VALUE
    num_uplus(VALUE num)
    {
        return num;
    }

-self → numeric click to toggle source

Unary Minus—Returns the receiver, negated.

    static VALUE
    num_uminus(VALUE num)
    {
        VALUE zero;

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

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

self <=> other → zero or nil click to toggle source

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

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

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

abs → numeric click to toggle source

Returns the absolute value of `self`.

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

`Numeric#magnitude` is an alias for `Numeric#abs`.

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

Also aliased as: magnitude
abs2 → real click to toggle source

Returns square of self.

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

angle → 0 or float

Returns 0 if the value is positive, pi otherwise.

Alias for: arg
arg → 0 or float click to toggle source

Returns 0 if the value is positive, pi otherwise.

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

Also aliased as: angle, phase
ceil(digits = 0) → integer or float click to toggle source

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

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

clone(freeze: true) → self click to toggle source

Returns `self`.

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

Related: `Numeric#dup`.

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

coerce(other) → array click to toggle source

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.

    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

Returns self.

Alias for: conjugate
conjugate -> self click to toggle source

Returns self.

    static VALUE
    numeric_conj(VALUE self)
    {
        return self;
    }

Also aliased as: conj
denominator → integer click to toggle source

Returns the denominator (always positive).

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

div(other) → integer click to toggle source

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, `Float`, `Rational`, and `Complex` use this implementation.

    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 click to toggle source

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

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

dup → self click to toggle source

Returns `self`.

Related: `Numeric#clone`.

    static VALUE
    num_dup(VALUE x)
    {
        return x;
    }

eql?(other) → true or false click to toggle source

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.

    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 click to toggle source

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.

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

finite? → true or false click to toggle source

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

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

floor(digits = 0) → integer or float click to toggle source

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

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

i → complex click to toggle source

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.

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

imag → 0

Returns zero.

Alias for: imaginary
imaginary -> 0 click to toggle source

Returns zero.

    static VALUE
    numeric_imag(VALUE self)
    {
        return INT2FIX(0);
    }

Also aliased as: imag
infinite? → -1, 1, or nil click to toggle source

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

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

integer? → true or false click to toggle source

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

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

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

magnitude()

Returns the absolute value of `self`.

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

`Numeric#magnitude` is an alias for `Numeric#abs`.

Alias for: abs
modulo(p1)

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:

    c % n
    c-n*(c/n).floor
    c.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)

`Numeric#modulo` is an alias for `Numeric#%`.

Alias for: %
negative? → true or false click to toggle source

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

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

nonzero? → self or nil click to toggle source

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.

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

numerator → integer click to toggle source

Returns the numerator.

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

phase → 0 or float

Returns 0 if the value is positive, pi otherwise.

Alias for: arg
polar → array click to toggle source

Returns an array; [num.abs, num.arg].

    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? → true or false click to toggle source

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

    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) → rat click to toggle source
quo(flo) → flo

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

    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 click to toggle source

Returns self.

    static VALUE
    numeric_real(VALUE self)
    {
        return self;
    }

real? → true or false click to toggle source

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

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

rect → array

Returns an array; [num, 0].

Alias for: rectangular
rectangular -> array click to toggle source

Returns an array; [num, 0].

    static VALUE
    numeric_rect(VALUE self)
    {
        return rb_assoc_new(self, INT2FIX(0));
    }

Also aliased as: rect
remainder(other) → real_number click to toggle source

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)

    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)))) {
            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 or float click to toggle source

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

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

step(to = nil, by = 1) {|n| ... } → self click to toggle source
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

    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 +step+ (which may not be zero).
    - Ends with the last number that is within or equal to +limit+;
      that is, less than or equal to +limit+ if +step+ is positive,
      greater than or equal to +limit+ if +step+ is negative.
      If +limit+ is not given, 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.

    <b>Keyword Arguments</b>

    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

    <b>Positional Arguments</b>

    With optional positional arguments +limit+ and +step+,
    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
    <i>floor(n + n*Float::EPSILON) + 1</i> times,
    where <i>n = (limit - self)/step</i>.

    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_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 → complex click to toggle source

Returns the value as a complex.

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

to_int → integer click to toggle source

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)

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

truncate(digits = 0) → integer or float click to toggle source

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

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

zero? → true or false click to toggle source

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

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

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