Support for the Ruby 2.4 series has ended. See here for reference.

In Files

  • complex.c
  • numeric.c
  • rational.c

Class/Module Index [+]

Quicksearch

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
puts 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 and duplication.

Integer.new(1)   #=> NoMethodError: undefined method `new' for Integer:Class
1.dup            #=> TypeError: can't dup Integer

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

Public Instance Methods

modulo(numeric) → real click to toggle source
x.modulo(y) means x-y*(x/y).floor

Equivalent to num.divmod(numeric)[1].

See Numeric#divmod.

 
               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));
}
            
+num → num click to toggle source

Unary Plus—Returns the receiver's value.

 
               static VALUE
num_uplus(VALUE num)
{
    return num;
}
            
-num → numeric click to toggle source

Unary Minus—Returns the receiver's value, negated.

 
               static VALUE
num_uminus(VALUE num)
{
    VALUE zero;

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

    return num_funcall1(zero, '-', num);
}
            
number <=> other → 0 or nil click to toggle source

Returns zero if number equals other, otherwise nil is returned if the two values are incomparable.

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

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

Numeric#magnitude is an alias of Numeric#abs.

 
               static VALUE
num_abs(VALUE num)
{
    if (negative_int_p(num)) {
        return num_funcall0(num, idUMinus);
    }
    return num;
}
            
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 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);
}
            
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);
}
            
ceil([ndigits]) → integer or float click to toggle source

Returns the smallest possible Integer that is greater than or equal to num.

Numeric achieves this by converting itself to a Float then invoking Float#ceil.

1.ceil        #=> 1
1.2.ceil      #=> 2
(-1.2).ceil   #=> -1
(-1.0).ceil   #=> -1
 
               static VALUE
num_ceil(int argc, VALUE *argv, VALUE num)
{
    return flo_ceil(argc, argv, rb_Float(num));
}
            
coerce(numeric) → array click to toggle source

If a numeric is the same type as num, returns an array containing numeric and num. Otherwise, returns an array with both a numeric and num represented as Float objects.

This coercion mechanism is used by Ruby to handle mixed-type numeric operations: it is intended to find a compatible common type between the two operands of the operator.

1.coerce(2.5)   #=> [2.5, 1.0]
1.2.coerce(3)   #=> [3.0, 1.2]
1.coerce(2)     #=> [2, 1]
 
               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 click to toggle source
conjugate → self

Returns self.

 
               static VALUE
numeric_conj(VALUE self)
{
    return self;
}
            
conjugate → self click to toggle source

Returns self.

 
               static VALUE
numeric_conj(VALUE self)
{
    return self;
}
            
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(numeric) → integer click to toggle source

Uses / to perform division, then converts the result to an integer. numeric does not define the / operator; this is left to subclasses.

Equivalent to num.divmod(numeric)[0].

See Numeric#divmod.

 
               static VALUE
num_div(VALUE x, VALUE y)
{
    if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
    return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0);
}
            
divmod(numeric) → array click to toggle source

Returns an array containing the quotient and modulus obtained by dividing num by numeric.

If q, r = * x.divmod(y), then

q = floor(x/y)
x = q*y+r

The quotient is rounded toward -infinity, as shown in the following table:

 a    |  b  |  a.divmod(b)  |   a/b   | a.modulo(b) | a.remainder(b)
------+-----+---------------+---------+-------------+---------------
 13   |  4  |   3,    1     |   3     |    1        |     1
------+-----+---------------+---------+-------------+---------------
 13   | -4  |  -4,   -3     |  -4     |   -3        |     1
------+-----+---------------+---------+-------------+---------------
-13   |  4  |  -4,    3     |  -4     |    3        |    -1
------+-----+---------------+---------+-------------+---------------
-13   | -4  |   3,   -1     |   3     |   -1        |    -1
------+-----+---------------+---------+-------------+---------------
 11.5 |  4  |   2,    3.5   |   2.875 |    3.5      |     3.5
------+-----+---------------+---------+-------------+---------------
 11.5 | -4  |  -3,   -0.5   |  -2.875 |   -0.5      |     3.5
------+-----+---------------+---------+-------------+---------------
-11.5 |  4  |  -3,    0.5   |  -2.875 |    0.5      |    -3.5
------+-----+---------------+---------+-------------+---------------
-11.5 | -4  |   2,   -3.5   |   2.875 |   -3.5      |    -3.5

Examples

11.divmod(3)         #=> [3, 2]
11.divmod(-3)        #=> [-4, -1]
11.divmod(3.5)       #=> [3, 0.5]
(-11).divmod(3.5)    #=> [-4, 3.0]
(11.5).divmod(3.5)   #=> [3, 1.0]
 
               static VALUE
num_divmod(VALUE x, VALUE y)
{
    return rb_assoc_new(num_div(x, y), num_modulo(x, y));
}
            
eql?(numeric) → true or false click to toggle source

Returns true if num and numeric are the same type and have equal values. Contrast this with Numeric#==, which performs type conversions.

1 == 1.0          #=> true
1.eql?(1.0)       #=> false
(1.0).eql?(1.0)   #=> true
68719476736.eql?(68719476736.0)   #=> false
 
               static VALUE
num_eql(VALUE x, VALUE y)
{
    if (TYPE(x) != TYPE(y)) return Qfalse;

    if (RB_TYPE_P(x, T_BIGNUM)) {
        return rb_big_eql(x, y);
    }

    return rb_equal(x, y);
}
            
fdiv(numeric) → float click to toggle source

Returns float division.

 
               static VALUE
num_fdiv(VALUE x, VALUE y)
{
    return rb_funcall(rb_Float(x), '/', 1, y);
}
            
finite? → true or false click to toggle source

Return true if num is finite number, oterwise returns false.

 
               static VALUE
num_finite_p(VALUE num)
{
    return Qtrue;
}
            
floor([ndigits]) → integer or float click to toggle source

Returns the largest integer less than or equal to num.

Numeric implements this by converting an Integer to a Float and invoking Float#floor.

1.floor      #=> 1
(-1).floor   #=> -1
 
               static VALUE
num_floor(int argc, VALUE *argv, VALUE num)
{
    return flo_floor(argc, argv, rb_Float(num));
}
            
i → Complex(0,num) click to toggle source

Returns the corresponding imaginary number. Not available for complex numbers.

 
               static VALUE
num_imaginary(VALUE num)
{
    return rb_complex_new(INT2FIX(0), num);
}
            
imag → 0 click to toggle source
imaginary → 0

Returns zero.

 
               static VALUE
numeric_imag(VALUE self)
{
    return INT2FIX(0);
}
            
imaginary → 0 click to toggle source

Returns zero.

 
               static VALUE
numeric_imag(VALUE self)
{
    return INT2FIX(0);
}
            
infinite? → nil or 1 or -1 click to toggle source

Returns values corresponding to the value of num's magnitude:

finite

nil

-Infinity

-1

+Infinity

+1

 
               static VALUE
num_infinite_p(VALUE num)
{
    return Qnil;
}
            
initialize_copy(p1) click to toggle source

Numerics are immutable values, which should not be copied.

Any attempt to use this method on a Numeric will raise a TypeError.

 
               static VALUE
num_init_copy(VALUE x, VALUE y)
{
    rb_raise(rb_eTypeError, "can't copy %"PRIsVALUE, rb_obj_class(x));

    UNREACHABLE;
}
            
integer? → true or false click to toggle source

Returns true if num is an Integer.

(1.0).integer? #=> false
(1).integer?   #=> true
 
               static VALUE
num_int_p(VALUE num)
{
    return Qfalse;
}
            
magnitude → numeric click to toggle source

Returns the absolute value of num.

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

Numeric#magnitude is an alias of Numeric#abs.

 
               static VALUE
num_abs(VALUE num)
{
    if (negative_int_p(num)) {
        return num_funcall0(num, idUMinus);
    }
    return num;
}
            
modulo(numeric) → real click to toggle source
x.modulo(y) means x-y*(x/y).floor

Equivalent to num.divmod(numeric)[1].

See Numeric#divmod.

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