123456789_123456789_123456789_123456789_123456789_

Class: Complex

Relationships & Source Files
Namespace Children
Classes:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Numeric
Instance Chain:
Inherits: Numeric
Defined in: complex.c

Overview

A Complex object houses a pair of values, given when the object is created as either rectangular coordinates or polar coordinates.

Rectangular Coordinates

The rectangular coordinates of a complex number are called the real and imaginary parts; see number definition.

You can create a Complex object from rectangular coordinates with:

  • A complex literal.

  • Method .rect.

  • Method Kernel.Complex, either with numeric arguments or with certain string arguments.

  • Method String#to_c, for certain strings.

Note that each of the stored parts may be a an instance one of the classes Complex, ::Float, ::Integer, or Rational; they may be retrieved:

The corresponding (computed) polar values may be retrieved:

  • Separately, with methods #abs and #arg.

  • Together, with method #polar.

Polar Coordinates

The polar coordinates of a complex number are called the absolute and argument parts; see polar plane.

In this class, the argument part in expressed radians (not ) degrees).

You can create a Complex object from polar coordinates with:

Note that each of the stored parts may be a an instance one of the classes Complex, ::Float, ::Integer, or Rational; they may be retrieved:

  • Separately, with methods #abs and #arg.

  • Together, with method #polar.

The corresponding (computed) rectangular values may be retrieved:

What’s Here

First, what’s elsewhere:

  • Class Complex inherits (directly or indirectly) from classes Numeric and Object.

  • Includes (indirectly) module Comparable.

Here, class Complex has methods for:

Creating Complex Objects

  • .polar: Returns a new Complex object based on given polar coordinates.

  • .rect (and its alias .rectangular): Returns a new Complex object based on given rectangular coordinates.

Querying

  • #abs (and its alias #magnitude): Returns the absolute value for self.

  • #arg (and its aliases #angle and #phase): Returns the argument (angle) for self in radians.

  • #denominator: Returns the denominator of self.

  • #finite?: Returns whether both self.real and self.image are finite.

  • #hash: Returns the integer hash value for self.

  • #imag (and its alias #imaginary): Returns the imaginary value for self.

  • #infinite?: Returns whether self.real or self.image is infinite.

  • #numerator: Returns the numerator of self.

  • #polar: Returns the array [self.abs, self.arg].

  • #inspect: Returns a string representation of self.

  • #real: Returns the real value for self.

  • #real?: Returns false; for compatibility with Numeric#real?.

  • #rect (and its alias #rectangular): Returns the array [self.real, self.imag].

Comparing

  • #<=>: Returns whether self is less than, equal to, or greater than the given argument.

  • #==: Returns whether self is equal to the given argument.

Converting

  • #rationalize: Returns a ::Rational object whose value is exactly or approximately equivalent to that of self.real.

  • #to_c: Returns self.

  • #to_d: Returns the value as a BigDecimal object.

  • #to_f: Returns the value of self.real as a ::Float, if possible.

  • #to_i: Returns the value of self.real as an ::Integer, if possible.

  • #to_r: Returns the value of self.real as a ::Rational, if possible.

  • #to_s: Returns a string representation of self.

Performing Complex Arithmetic

  • #*: Returns the product of self and the given numeric.

  • #**: Returns self raised to power of the given numeric.

  • #+: Returns the sum of self and the given numeric.

  • #-: Returns the difference of self and the given numeric.

  • #-@: Returns the negation of self.

  • #/: Returns the quotient of self and the given numeric.

  • #abs2: Returns square of the absolute value (magnitude) for self.

  • #conj (and its alias #conjugate): Returns the conjugate of self.

  • #fdiv: Returns Complex.rect(self.real/numeric, self.imag/numeric).

Working with JSON

  • .json_create: Returns a new Complex object, deserialized from the given serialized hash.

  • #as_json: Returns a serialized hash constructed from self.

  • #to_json: Returns a JSON string representing self.

These methods are provided by the JSON gem. To make these methods available:

require 'json/add/complex'

Constant Summary

Class Method Summary

Instance Attribute Summary

::Numeric - Inherited

#finite?

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

#infinite?

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

#integer?

Returns true if self is an ::Integer.

#negative?

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

#nonzero?

Returns self if self is not a zero value, nil otherwise; uses method zero? for the evaluation.

#positive?

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

#real?

Returns true if self is a real number (i.e.

#zero?

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

Instance Method Summary

::Numeric - Inherited

#%

Returns self modulo other as a real number.

#+@

Returns self.

#-@

Unary Minus—Returns the receiver, negated.

#<=>

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

#abs

Returns the absolute value of self.

#abs2

Returns the square of self.

#angle

Alias for Numeric#arg.

#arg

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

#ceil

Returns the smallest float or integer that is greater than or equal to self, as specified by the given ndigits, which must be an integer-convertible object.

#clone

Returns self.

#coerce

Returns a 2-element array containing two numeric elements, formed from the two operands self and other, of a common compatible type.

#conj
#conjugate

Returns self.

#denominator

Returns the denominator (always positive).

#div

Returns the quotient self/other as an integer (via floor), using method #/ in the derived class of self.

#divmod

Returns a 2-element array [q, r], where.

#dup

Returns self.

#eql?

Returns true if self and other are the same type and have equal values.

#fdiv

Returns the quotient self/other as a float, using method #/ in the derived class of self.

#floor

Returns the largest float or integer that is less than or equal to self, as specified by the given ndigits, which must be an integer-convertible object.

#i

Returns Complex(0, self):

#imag
#imaginary

Returns zero.

#magnitude

Alias for Numeric#abs.

#modulo

Alias for Numeric#%.

#numerator

Returns the numerator.

#phase

Alias for Numeric#arg.

#polar

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

#quo

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

#real

Returns self.

#rect

Returns array [self, 0].

#rectangular

Alias for Numeric#rect.

#remainder

Returns the remainder after dividing self by other.

#round

Returns self rounded to the nearest value with a precision of digits decimal digits.

#step

Generates a sequence of numbers; with a block given, traverses the sequence.

#to_c

Returns self as a Complex object.

#to_int

Returns self as an integer; converts using method #to_i in the derived class.

#truncate

Returns self truncated (toward zero) to a precision of digits decimal digits.

#singleton_method_added

Trap attempts to add methods to ::Numeric objects.

::Comparable - Included

#<

Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than 0.

#<=

Compares two objects based on the receiver’s #<=> method, returning true if it returns a value less than or equal to 0.

#==

Compares two objects based on the receiver’s #<=> method, returning true if it returns 0.

#>

Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than 0.

#>=

Compares two objects based on the receiver’s #<=> method, returning true if it returns a value greater than or equal to 0.

#between?

Returns false if obj #<=> min is less than zero or if obj #<=> max is greater than zero, true otherwise.

#clamp

In (min, max) form, returns min if obj #<=> min is less than zero, max if obj #<=> max is greater than zero, and obj otherwise.

Class Method Details

.polar(abs, arg = 0) ⇒ Complex

Returns a new Complex object formed from the arguments, each of which must be an instance of ::Numeric, or an instance of one of its subclasses: Complex, ::Float, ::Integer, ::Rational. Argument #arg is given in radians; see Polar Coordinates:

Complex.polar(3)        # => (3+0i)
Complex.polar(3, 2.0)   # => (-1.2484405096414273+2.727892280477045i)
Complex.polar(-3, -2.0) # => (1.2484405096414273+2.727892280477045i)
[ GitHub ]

  
# File 'complex.c', line 738

static VALUE
nucomp_s_polar(int argc, VALUE *argv, VALUE klass)
{
    VALUE abs, arg;

    argc = rb_scan_args(argc, argv, "11", &abs, &arg);
    abs = nucomp_real_check(abs);
    if (argc == 2) {
        arg = nucomp_real_check(arg);
    }
    else {
        arg = ZERO;
    }
    return f_complex_polar_real(klass, abs, arg);
}

.rect(real, imag = 0) ⇒ Complex Also known as: .rectangular

Returns a new Complex object formed from the arguments, each of which must be an instance of ::Numeric, or an instance of one of its subclasses: Complex, ::Float, ::Integer, Rational; see Rectangular Coordinates:

Complex.rect(3)             # => (3+0i)
Complex.rect(3, Math::PI)   # => (3+3.141592653589793i)
Complex.rect(-3, -Math::PI) # => (-3-3.141592653589793i)

Complex.rectangular is an alias for Complex.rect.

[ GitHub ]

  
# File 'complex.c', line 492

static VALUE
nucomp_s_new(int argc, VALUE *argv, VALUE klass)
{
    VALUE real, imag;

    switch (rb_scan_args(argc, argv, "11", &real, &imag)) {
      case 1:
        real = nucomp_real_check(real);
        imag = ZERO;
        break;
      default:
        real = nucomp_real_check(real);
        imag = nucomp_real_check(imag);
        break;
    }

    return nucomp_s_new_internal(klass, real, imag);
}

.rect(real, imag = 0) ⇒ Complex .rectangular(real, imag = 0) ⇒ Complex

Alias for .rect.

Instance Attribute Details

#finite?Boolean (readonly)

Returns true if both self.real.finite? and self.imag.finite? are true, false otherwise:

Complex.rect(1, 1).finite?               # => true
Complex.rect(Float::INFINITY, 0).finite? # => false

Related: Numeric#finite?, Float#finite?.

[ GitHub ]

  
# File 'complex.c', line 1673

static VALUE
rb_complex_finite_p(VALUE self)
{
    get_dat1(self);

    return RBOOL(f_finite_p(dat->real) && f_finite_p(dat->imag));
}

#infinite?Boolean (readonly)

Returns 1 if either self.real.infinite? or self.imag.infinite? is true, nil otherwise:

Complex.rect(Float::INFINITY, 0).infinite? # => 1
Complex.rect(1, 1).infinite?               # => nil

Related: Numeric#infinite?, Float#infinite?.

[ GitHub ]

  
# File 'complex.c', line 1693

static VALUE
rb_complex_infinite_p(VALUE self)
{
    get_dat1(self);

    if (!f_infinite_p(dat->real) && !f_infinite_p(dat->imag)) {
        return Qnil;
    }
    return ONE;
}

#realNumeric (readonly)

Returns the real value for self:

Complex.rect(7).real     # => 7
Complex.rect(9, -4).real # => 9

If self was created with polar coordinates, the returned value is computed, and may be inexact:

Complex.polar(1, Math::PI/4).real # => 0.7071067811865476 # Square root of 2.
[ GitHub ]

  
# File 'complex.c', line 770

VALUE
rb_complex_real(VALUE self)
{
    get_dat1(self);
    return dat->real;
}

#real?Boolean (readonly)

Returns false; for compatibility with Numeric#real?.

[ GitHub ]

  
# File 'complex.c', line 1468

static VALUE
nucomp_real_p_m(VALUE self)
{
    return Qfalse;
}

Instance Method Details

#*(numeric) ⇒ Complex

Returns the product of self and numeric:

Complex.rect(2, 3)  * Complex.rect(2, 3)  # => (-5+12i)
Complex.rect(900)   * Complex.rect(1)     # => (900+0i)
Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i)
Complex.rect(9, 8)  * 4                   # => (36+32i)
Complex.rect(20, 9) * 9.8                 # => (196.0+88.2i)
[ GitHub ]

  
# File 'complex.c', line 927

VALUE
rb_complex_mul(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX)) {
        VALUE real, imag;
        get_dat2(self, other);

        comp_mul(adat->real, adat->imag, bdat->real, bdat->imag, &real, &imag);

        return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
        get_dat1(self);

        return f_complex_new2(CLASS_OF(self),
                              f_mul(dat->real, other),
                              f_mul(dat->imag, other));
    }
    return rb_num_coerce_bin(self, other, '*');
}

#**(numeric) ⇒ Complex

Returns self raised to power numeric:

Complex.rect(0, 1) ** 2            # => (-1+0i)
Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i)
[ GitHub ]

  
# File 'complex.c', line 1122

VALUE
rb_complex_pow(VALUE self, VALUE other)
{
    if (k_numeric_p(other) && k_exact_zero_p(other))
        return f_complex_new_bang1(CLASS_OF(self), ONE);

    if (RB_TYPE_P(other, T_RATIONAL) && RRATIONAL(other)->den == LONG2FIX(1))
        other = RRATIONAL(other)->num; /* c14n */

    if (RB_TYPE_P(other, T_COMPLEX)) {
        get_dat1(other);

        if (k_exact_zero_p(dat->imag))
            other = dat->real; /* c14n */
    }

    if (other == ONE) {
        get_dat1(self);
        return nucomp_s_new_internal(CLASS_OF(self), dat->real, dat->imag);
    }

    VALUE result = complex_pow_for_special_angle(self, other);
    if (!UNDEF_P(result)) return result;

    if (RB_TYPE_P(other, T_COMPLEX)) {
        VALUE r, theta, nr, ntheta;

        get_dat1(other);

        r = f_abs(self);
        theta = f_arg(self);

        nr = m_exp_bang(f_sub(f_mul(dat->real, m_log_bang(r)),
                              f_mul(dat->imag, theta)));
        ntheta = f_add(f_mul(theta, dat->real),
                       f_mul(dat->imag, m_log_bang(r)));
        return f_complex_polar(CLASS_OF(self), nr, ntheta);
    }
    if (FIXNUM_P(other)) {
        long n = FIX2LONG(other);
        if (n == 0) {
            return nucomp_s_new_internal(CLASS_OF(self), ONE, ZERO);
        }
        if (n < 0) {
            self = f_reciprocal(self);
            other = rb_int_uminus(other);
            n = -n;
        }
        {
            get_dat1(self);
            VALUE xr = dat->real, xi = dat->imag, zr = xr, zi = xi;

            if (f_zero_p(xi)) {
                zr = rb_num_pow(zr, other);
            }
            else if (f_zero_p(xr)) {
                zi = rb_num_pow(zi, other);
                if (n & 2) zi = f_negate(zi);
                if (!(n & 1)) {
                    VALUE tmp = zr;
                    zr = zi;
                    zi = tmp;
                }
            }
            else {
                while (--n) {
                    long q, r;

                    for (; q = n / 2, r = n % 2, r == 0; n = q) {
                        VALUE tmp = f_sub(f_mul(xr, xr), f_mul(xi, xi));
                        xi = f_mul(f_mul(TWO, xr), xi);
                        xr = tmp;
                    }
                    comp_mul(zr, zi, xr, xi, &zr, &zi);
                }
            }
            return nucomp_s_new_internal(CLASS_OF(self), zr, zi);
        }
    }
    if (k_numeric_p(other) && f_real_p(other)) {
        VALUE r, theta;

        if (RB_BIGNUM_TYPE_P(other))
            rb_warn("in a**b, b may be too big");

        r = f_abs(self);
        theta = f_arg(self);

        return f_complex_polar(CLASS_OF(self), f_expt(r, other),
                               f_mul(theta, other));
    }
    return rb_num_coerce_bin(self, other, id_expt);
}

#+(numeric) ⇒ Complex

Returns the sum of self and numeric:

Complex.rect(2, 3)  + Complex.rect(2, 3)  # => (4+6i)
Complex.rect(900)   + Complex.rect(1)     # => (901+0i)
Complex.rect(-2, 9) + Complex.rect(-9, 2) # => (-11+11i)
Complex.rect(9, 8)  + 4                   # => (13+8i)
Complex.rect(20, 9) + 9.8                 # => (29.8+9i)
[ GitHub ]

  
# File 'complex.c', line 831

VALUE
rb_complex_plus(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX)) {
        VALUE real, imag;

        get_dat2(self, other);

        real = f_add(adat->real, bdat->real);
        imag = f_add(adat->imag, bdat->imag);

        return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
        get_dat1(self);

        return f_complex_new2(CLASS_OF(self),
                              f_add(dat->real, other), dat->imag);
    }
    return rb_num_coerce_bin(self, other, '+');
}

#-(numeric) ⇒ Complex

Returns the difference of self and numeric:

Complex.rect(2, 3)  - Complex.rect(2, 3)  # => (0+0i)
Complex.rect(900)   - Complex.rect(1)     # => (899+0i)
Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i)
Complex.rect(9, 8)  - 4                   # => (5+8i)
Complex.rect(20, 9) - 9.8                 # => (10.2+9i)
[ GitHub ]

  
# File 'complex.c', line 866

VALUE
rb_complex_minus(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX)) {
        VALUE real, imag;

        get_dat2(self, other);

        real = f_sub(adat->real, bdat->real);
        imag = f_sub(adat->imag, bdat->imag);

        return f_complex_new2(CLASS_OF(self), real, imag);
    }
    if (k_numeric_p(other) && f_real_p(other)) {
        get_dat1(self);

        return f_complex_new2(CLASS_OF(self),
                              f_sub(dat->real, other), dat->imag);
    }
    return rb_num_coerce_bin(self, other, '-');
}

#-Complex

Returns the negation of self, which is the negation of each of its parts:

-Complex.rect(1, 2)   # => (-1-2i)
-Complex.rect(-1, -2) # => (1+2i)
[ GitHub ]

  
# File 'complex.c', line 810

VALUE
rb_complex_uminus(VALUE self)
{
    get_dat1(self);
    return f_complex_new2(CLASS_OF(self),
                          f_negate(dat->real), f_negate(dat->imag));
}

#/(numeric) ⇒ Complex

Returns the quotient of self and numeric:

Complex.rect(2, 3)  / Complex.rect(2, 3)  # => (1+0i)
Complex.rect(900)   / Complex.rect(1)     # => (900+0i)
Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i)
Complex.rect(9, 8)  / 4                   # => ((9/4)+2i)
Complex.rect(20, 9) / 9.8                 # => (2.0408163265306123+0.9183673469387754i)
[ GitHub ]

  
# File 'complex.c', line 1003

VALUE
rb_complex_div(VALUE self, VALUE other)
{
    return f_divide(self, other, f_quo, id_quo);
}

#<=>(object) ⇒ 1, ...

Returns:

  • self.real <=> object.real if both of the following are true:

    • self.imag == 0.

    • object.imag == 0. # Always true if object is numeric but not complex.

  • nil otherwise.

Examples:

Complex.rect(2) <=> 3                  # => -1
Complex.rect(2) <=> 2                  # => 0
Complex.rect(2) <=> 1                  # => 1
Complex.rect(2, 1) <=> 1               # => nil # self.imag not zero.
Complex.rect(1) <=> Complex.rect(1, 1) # => nil # object.imag not zero.
Complex.rect(1) <=> 'Foo'              # => nil # object.imag not defined.
[ GitHub ]

  
# File 'complex.c', line 1273

static VALUE
nucomp_cmp(VALUE self, VALUE other)
{
    if (!k_numeric_p(other)) {
        return rb_num_coerce_cmp(self, other, idCmp);
    }
    if (!nucomp_real_p(self)) {
        return Qnil;
    }
    if (RB_TYPE_P(other, T_COMPLEX)) {
        if (nucomp_real_p(other)) {
            get_dat2(self, other);
            return rb_funcall(adat->real, idCmp, 1, bdat->real);
        }
    }
    else {
        get_dat1(self);
        if (f_real_p(other)) {
            return rb_funcall(dat->real, idCmp, 1, other);
        }
        else {
            return rb_num_coerce_cmp(dat->real, other, idCmp);
        }
    }
    return Qnil;
}

#==(object) ⇒ Boolean

Returns true if self.real == object.real and self.imag == object.imag:

Complex.rect(2, 3)  == Complex.rect(2.0, 3.0) # => true
[ GitHub ]

  
# File 'complex.c', line 1226

static VALUE
nucomp_eqeq_p(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX)) {
        get_dat2(self, other);

        return RBOOL(f_eqeq_p(adat->real, bdat->real) &&
                          f_eqeq_p(adat->imag, bdat->imag));
    }
    if (k_numeric_p(other) && f_real_p(other)) {
        get_dat1(self);

        return RBOOL(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
    }
    return RBOOL(f_eqeq_p(other, self));
}

#absFloat Also known as: #magnitude

Returns the absolute value (magnitude) for self; see polar coordinates:

Complex.polar(-1, 0).abs # => 1.0

If self was created with rectangular coordinates, the returned value is computed, and may be inexact:

Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2.
[ GitHub ]

  
# File 'complex.c', line 1330

VALUE
rb_complex_abs(VALUE self)
{
    get_dat1(self);

    if (f_zero_p(dat->real)) {
        VALUE a = f_abs(dat->imag);
        if (RB_FLOAT_TYPE_P(dat->real) && !RB_FLOAT_TYPE_P(dat->imag))
            a = f_to_f(a);
        return a;
    }
    if (f_zero_p(dat->imag)) {
        VALUE a = f_abs(dat->real);
        if (!RB_FLOAT_TYPE_P(dat->real) && RB_FLOAT_TYPE_P(dat->imag))
            a = f_to_f(a);
        return a;
    }
    return rb_math_hypot(dat->real, dat->imag);
}

#abs2Float

Returns square of the absolute value (magnitude) for self; see polar coordinates:

Complex.polar(2, 2).abs2 # => 4.0

If self was created with rectangular coordinates, the returned value is computed, and may be inexact:

Complex.rectangular(1.0/3, 1.0/3).abs2 # => 0.2222222222222222
[ GitHub ]

  
# File 'complex.c', line 1366

static VALUE
nucomp_abs2(VALUE self)
{
    get_dat1(self);
    return f_add(f_mul(dat->real, dat->real),
                 f_mul(dat->imag, dat->imag));
}

#argFloat #angleFloat

Alias for #arg.

#argFloat Also known as: #angle, #phase

Returns the argument (angle) for self in radians; see polar coordinates:

Complex.polar(3, Math::PI/2).arg  # => 1.57079632679489660

If self was created with rectangular coordinates, the returned value is computed, and may be inexact:

Complex.polar(1, 1.0/3).arg # => 0.33333333333333326
[ GitHub ]

  
# File 'complex.c', line 1390

VALUE
rb_complex_arg(VALUE self)
{
    get_dat1(self);
    return rb_math_atan2(dat->imag, dat->real);
}

#coerce(other)

This method is for internal use only.
[ GitHub ]

  
# File 'complex.c', line 1301

static VALUE
nucomp_coerce(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX))
        return rb_assoc_new(other, self);
    if (k_numeric_p(other) && f_real_p(other))
        return rb_assoc_new(f_complex_new_bang1(CLASS_OF(self), other), self);

    rb_raise(rb_eTypeError, "%"PRIsVALUE" can't be coerced into %"PRIsVALUE,
             rb_obj_class(other), rb_obj_class(self));
    return Qnil;
}

#conjComplex Also known as: #conjugate

Returns the conjugate of self, Complex.rect(self.imag, self.real):

Complex.rect(1, 2).conj # => (1-2i)
[ GitHub ]

  
# File 'complex.c', line 1455

VALUE
rb_complex_conjugate(VALUE self)
{
    get_dat1(self);
    return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}

#conjComplex #conjugateComplex

Alias for #conj.

#denominatorInteger

Returns the denominator of self, which is the least common multiple of self.real.denominator and self.imag.denominator:

Complex.rect(Rational(1, 2), Rational(2, 3)).denominator # => 6

Note that n.denominator of a non-rational numeric is 1.

Related: #numerator.

[ GitHub ]

  
# File 'complex.c', line 1488

static VALUE
nucomp_denominator(VALUE self)
{
    get_dat1(self);
    return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
}

#eql?(other) ⇒ Boolean

This method is for internal use only.
[ GitHub ]

  
# File 'complex.c', line 1565

static VALUE
nucomp_eql_p(VALUE self, VALUE other)
{
    if (RB_TYPE_P(other, T_COMPLEX)) {
        get_dat2(self, other);

        return RBOOL((CLASS_OF(adat->real) == CLASS_OF(bdat->real)) &&
                          (CLASS_OF(adat->imag) == CLASS_OF(bdat->imag)) &&
                          f_eqeq_p(self, other));

    }
    return Qfalse;
}

#fdiv(numeric) ⇒ Complex

Returns Complex.rect(self.real/numeric, self.imag/numeric):

Complex.rect(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i)
[ GitHub ]

  
# File 'complex.c', line 1020

static VALUE
nucomp_fdiv(VALUE self, VALUE other)
{
    return f_divide(self, other, f_fdiv, id_fdiv);
}

#hashInteger

Returns the integer hash value for self.

Two Complex objects created from the same values will have the same hash value (and will compare using #eql?):

Complex.rect(1, 2).hash == Complex.rect(1, 2).hash # => true
[ GitHub ]

  
# File 'complex.c', line 1558

static VALUE
nucomp_hash(VALUE self)
{
    return ST2FIX(rb_complex_hash(self));
}

#imagNumeric Also known as: #imaginary

Returns the imaginary value for self:

Complex.rect(7).imag     # => 0
Complex.rect(9, -4).imag # => -4

If self was created with polar coordinates, the returned value is computed, and may be inexact:

Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2.
[ GitHub ]

  
# File 'complex.c', line 793

VALUE
rb_complex_imag(VALUE self)
{
    get_dat1(self);
    return dat->imag;
}

#imagNumeric #imaginaryNumeric

Alias for #imag.

#inspectString

Returns a string representation of self:

Complex.rect(2).inspect                      # => "(2+0i)"
Complex.rect(-8, 6).inspect                  # => "(-8+6i)"
Complex.rect(0, Rational(1, 2)).inspect      # => "(0+(1/2)*i)"
Complex.rect(0, Float::INFINITY).inspect     # => "(0+Infinity*i)"
Complex.rect(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)"
[ GitHub ]

  
# File 'complex.c', line 1647

static VALUE
nucomp_inspect(VALUE self)
{
    VALUE s;

    s = rb_usascii_str_new2("(");
    f_format(self, s, rb_inspect);
    rb_str_cat2(s, ")");

    return s;
}

#absFloat #magnitudeFloat

Alias for #abs.

#marshal_dump (private)

This method is for internal use only.
[ GitHub ]

  
# File 'complex.c', line 1725

static VALUE
nucomp_marshal_dump(VALUE self)
{
    VALUE a;
    get_dat1(self);

    a = rb_assoc_new(dat->real, dat->imag);
    rb_copy_generic_ivar(a, self);
    return a;
}

#numeratorComplex

Returns the Complex object created from the numerators of the real and imaginary parts of self, after converting each part to the lowest common denominator of the two:

c = Complex.rect(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i)
c.numerator                                      # => (8+9i)

In this example, the lowest common denominator of the two parts is 12; the two converted parts may be thought of as Rational(8, 12) and Rational(9, 12), whose numerators, respectively, are 8 and 9; so the returned value of c.numerator is Complex.rect(8, 9).

Related: #denominator.

[ GitHub ]

  
# File 'complex.c', line 1515

static VALUE
nucomp_numerator(VALUE self)
{
    VALUE cd;

    get_dat1(self);

    cd = nucomp_denominator(self);
    return f_complex_new2(CLASS_OF(self),
                          f_mul(f_numerator(dat->real),
                                f_div(cd, f_denominator(dat->real))),
                          f_mul(f_numerator(dat->imag),
                                f_div(cd, f_denominator(dat->imag))));
}

#argFloat #phaseFloat

Alias for #arg.

#polarArray

Returns the array [self.abs, self.arg]:

Complex.polar(1, 2).polar # => [1.0, 2.0]

See Polar Coordinates.

If self was created with rectangular coordinates, the returned value is computed, and may be inexact:

Complex.rect(1, 1).polar # => [1.4142135623730951, 0.7853981633974483]
[ GitHub ]

  
# File 'complex.c', line 1440

static VALUE
nucomp_polar(VALUE self)
{
    return rb_assoc_new(f_abs(self), f_arg(self));
}

#quo

[ GitHub ]

#rationalize(epsilon = nil) ⇒ Rational

Returns a ::Rational object whose value is exactly or approximately equivalent to that of self.real.

With no argument epsilon given, returns a Rational object whose value is exactly equal to that of self.real.rationalize:

Complex.rect(1, 0).rationalize              # => (1/1)
Complex.rect(1, Rational(0, 1)).rationalize # => (1/1)
Complex.rect(3.14159, 0).rationalize        # => (314159/100000)

With argument epsilon given, returns a Rational object whose value is exactly or approximately equal to that of self.real to the given precision:

Complex.rect(3.14159, 0).rationalize(0.1)          # => (16/5)
Complex.rect(3.14159, 0).rationalize(0.01)         # => (22/7)
Complex.rect(3.14159, 0).rationalize(0.001)        # => (201/64)
Complex.rect(3.14159, 0).rationalize(0.0001)       # => (333/106)
Complex.rect(3.14159, 0).rationalize(0.00001)      # => (355/113)
Complex.rect(3.14159, 0).rationalize(0.000001)     # => (7433/2366)
Complex.rect(3.14159, 0).rationalize(0.0000001)    # => (9208/2931)
Complex.rect(3.14159, 0).rationalize(0.00000001)   # => (47460/15107)
Complex.rect(3.14159, 0).rationalize(0.000000001)  # => (76149/24239)
Complex.rect(3.14159, 0).rationalize(0.0000000001) # => (314159/100000)
Complex.rect(3.14159, 0).rationalize(0.0)          # => (3537115888337719/1125899906842624)

Related: #to_r.

[ GitHub ]

  
# File 'complex.c', line 1901

static VALUE
nucomp_rationalize(int argc, VALUE *argv, VALUE self)
{
    get_dat1(self);

    rb_check_arity(argc, 0, 1);

    if (!k_exact_zero_p(dat->imag)) {
       rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
                self);
    }
    return rb_funcallv(dat->real, id_rationalize, argc, argv);
}

#rectArray Also known as: #rectangular

Returns the array [self.real, self.imag]:

Complex.rect(1, 2).rect # => [1, 2]

See Rectangular Coordinates.

If self was created with polar coordinates, the returned value is computed, and may be inexact:

Complex.polar(1.0, 1.0).rect # => [0.5403023058681398, 0.8414709848078965]

#rectangular is an alias for rect.

[ GitHub ]

  
# File 'complex.c', line 1416

static VALUE
nucomp_rect(VALUE self)
{
    get_dat1(self);
    return rb_assoc_new(dat->real, dat->imag);
}

#rectArray #rectangularArray

Alias for #rect.

#to_cself

Returns self.

[ GitHub ]

  
# File 'complex.c', line 1921

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

#to_fFloat

Returns the value of self.real as a ::Float, if possible:

Complex.rect(1, 0).to_f              # => 1.0
Complex.rect(1, Rational(0, 1)).to_f # => 1.0

Raises RangeError if self.imag is not exactly zero (either Integer(0) or Rational(0, n)).

[ GitHub ]

  
# File 'complex.c', line 1823

static VALUE
nucomp_to_f(VALUE self)
{
    get_dat1(self);

    if (!k_exact_zero_p(dat->imag)) {
        rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Float",
                 self);
    }
    return f_to_f(dat->real);
}

#to_iInteger

Returns the value of self.real as an ::Integer, if possible:

Complex.rect(1, 0).to_i              # => 1
Complex.rect(1, Rational(0, 1)).to_i # => 1

Raises RangeError if self.imag is not exactly zero (either Integer(0) or Rational(0, n)).

[ GitHub ]

  
# File 'complex.c', line 1799

static VALUE
nucomp_to_i(VALUE self)
{
    get_dat1(self);

    if (!k_exact_zero_p(dat->imag)) {
        rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Integer",
                 self);
    }
    return f_to_i(dat->real);
}

#to_rRational

Returns the value of self.real as a ::Rational, if possible:

Complex.rect(1, 0).to_r              # => (1/1)
Complex.rect(1, Rational(0, 1)).to_r # => (1/1)
Complex.rect(1, 0.0).to_r            # => (1/1)

Raises RangeError if self.imag is not exactly zero (either Integer(0) or Rational(0, n)) and self.imag.to_r is not exactly zero.

Related: #rationalize.

[ GitHub ]

  
# File 'complex.c', line 1851

static VALUE
nucomp_to_r(VALUE self)
{
    get_dat1(self);

    if (RB_FLOAT_TYPE_P(dat->imag) && FLOAT_ZERO_P(dat->imag)) {
        /* Do nothing here */
    }
    else if (!k_exact_zero_p(dat->imag)) {
        VALUE imag = rb_check_convert_type_with_id(dat->imag, T_RATIONAL, "Rational", idTo_r);
        if (NIL_P(imag) || !k_exact_zero_p(imag)) {
            rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational",
                     self);
        }
    }
    return f_to_r(dat->real);
}

#to_sString

Returns a string representation of self:

Complex.rect(2).to_s                      # => "2+0i"
Complex.rect(-8, 6).to_s                  # => "-8+6i"
Complex.rect(0, Rational(1, 2)).to_s      # => "0+1/2i"
Complex.rect(0, Float::INFINITY).to_s     # => "0+Infinity*i"
Complex.rect(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i"
[ GitHub ]

  
# File 'complex.c', line 1628

static VALUE
nucomp_to_s(VALUE self)
{
    return f_format(self, rb_usascii_str_new2(""), rb_String);
}