Class: Complex

Inherits:
Numeric show all
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 Complex number definition.

You can create a Complex object from rectangular coordinates with:

  • A complex literal.

  • Method Complex.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:

  • Separately, with methods Complex#real and Complex#imaginary.

  • Together, with method Complex#rect.

The corresponding (computed) polar values may be retrieved:

  • Separately, with methods Complex#abs and Complex#arg.

  • Together, with method Complex#polar.

Polar Coordinates

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

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

You can create a Complex object from polar coordinates with:

  • Method Complex.polar.

  • Method Kernel#Complex, 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:

  • Separately, with methods Complex#abs and Complex#arg.

  • Together, with method Complex#polar.

The corresponding (computed) rectangular values may be retrieved:

  • Separately, with methods Complex#real and Complex#imag.

  • Together, with method Complex#rect.

Defined Under Namespace

Classes: compatible

Constant Summary collapse

I =

Complex::I # => (0+1i)

Equivalent
to <tt>Complex(0, 1)</tt>

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#%, #+@, #ceil, #clone, #div, #divmod, #dup, #floor, #i, #modulo, #negative?, #nonzero?, #positive?, #remainder, #round, #singleton_method_added, #step, #to_int, #truncate, #zero?

Methods included from Comparable

#<, #<=, #>, #>=, #between?, #clamp

Class Method Details

.polar(abs, arg = 0) ⇒ Object

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)


738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
# 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) ⇒ Object

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.



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# 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) ⇒ Object

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.



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# 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);
}

Instance Method Details

#*(numeric) ⇒ Object

Returns the product of self and numeric:

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


927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
# 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) ⇒ Object

Returns self raised to power numeric:

Complex('i') ** 2             # => (-1+0i)
Complex(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i)


1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
# File 'complex.c', line 1120

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 (result != Qundef) 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) ⇒ Object

Returns the sum of self and numeric:

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


831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
# 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) ⇒ Object

Returns the difference of self and numeric:

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


866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
# 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, '-');
}

#-Object

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

-Complex(1, 2)   # => (-1-2i)
-Complex(-1, -2) # => (1+2i)


810
811
812
813
814
815
816
# 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) ⇒ Object

Returns the quotient of self and numeric:

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


1003
1004
1005
1006
1007
# 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(2) <=> 3             # => -1
Complex(2) <=> 2             # => 0
Complex(2) <=> 1             # => 1
Complex(2, 1) <=> 1          # => nil # self.imag not zero.
Complex(1) <=> Complex(1, 1) # => nil # object.imag not zero.
Complex(1) <=> 'Foo'         # => nil # object.imag not defined.

Returns:

  • (-1, 0, 1, nil)


1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
# File 'complex.c', line 1271

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(2, 3)  == Complex(2.0, 3.0)      # => true

Returns:

  • (Boolean)


1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
# File 'complex.c', line 1224

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

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.

Returns:



1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
# File 'complex.c', line 1328

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

Returns:



1364
1365
1366
1367
1368
1369
1370
# File 'complex.c', line 1364

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

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

Returns:



1388
1389
1390
1391
1392
1393
# File 'complex.c', line 1388

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

#argFloat

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

Returns:



1388
1389
1390
1391
1392
1393
# File 'complex.c', line 1388

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

#coerce(other) ⇒ Object

:nodoc:



1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
# File 'complex.c', line 1299

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

#conjObject

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

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


1453
1454
1455
1456
1457
1458
# File 'complex.c', line 1453

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

#conjObject

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

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


1453
1454
1455
1456
1457
1458
# File 'complex.c', line 1453

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

#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: Complex#numerator.

Returns:



1486
1487
1488
1489
1490
1491
# File 'complex.c', line 1486

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

#eql?(other) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
# File 'complex.c', line 1563

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) ⇒ Object

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

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


1020
1021
1022
1023
1024
# File 'complex.c', line 1020

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

#finite?Boolean

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

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

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

Returns:

  • (Boolean)


1672
1673
1674
1675
1676
1677
1678
# File 'complex.c', line 1672

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

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

#hashObject

:call-seq:

hash -> integer

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(1, 2).hash == Complex(1, 2).hash # => true


1556
1557
1558
1559
1560
# File 'complex.c', line 1556

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

#imagNumeric

Returns the imaginary value for self:

Complex(7).imaginary      #=> 0
Complex(9, -4).imaginary  #=> -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.

Returns:



793
794
795
796
797
798
# File 'complex.c', line 793

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

#imagNumeric

Returns the imaginary value for self:

Complex(7).imaginary      #=> 0
Complex(9, -4).imaginary  #=> -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.

Returns:



793
794
795
796
797
798
# File 'complex.c', line 793

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

#infinite?1?

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

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

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

Returns:

  • (1, nil)


1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
# File 'complex.c', line 1692

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

#inspectString

Returns a string representation of self:

Complex(2).inspect                      # => "(2+0i)"
Complex('-8/6').inspect                 # => "((-4/3)+0i)"
Complex('1/2i').inspect                 # => "(0+(1/2)*i)"
Complex(0, Float::INFINITY).inspect     # => "(0+Infinity*i)"
Complex(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)"

Returns:



1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
# File 'complex.c', line 1646

static VALUE
nucomp_inspect(VALUE self)
{
    VALUE s;

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

    return s;
}

#absFloat

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.

Returns:



1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
# File 'complex.c', line 1328

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

#marshal_dumpObject (private)

:nodoc:



1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
# File 'complex.c', line 1724

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

#numeratorObject

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(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(8, 9).

Related: Complex#denominator.



1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
# File 'complex.c', line 1513

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

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

Returns:



1388
1389
1390
1391
1392
1393
# File 'complex.c', line 1388

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

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

Returns:



1438
1439
1440
1441
1442
# File 'complex.c', line 1438

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

#quoObject

#rationalize(epsilon = nil) ⇒ Object

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

Related: Complex#to_r.



1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
# File 'complex.c', line 1892

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

#realNumeric

Returns the real value for self:

Complex(7).real      #=> 7
Complex(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.

Returns:



770
771
772
773
774
775
# File 'complex.c', line 770

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

#real?false

Returns false; for compatibility with Numeric#real?.

Returns:

  • (false)


1466
1467
1468
1469
1470
# File 'complex.c', line 1466

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

#rectArray

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]

Complex#rectangular is an alias for Complex#rect.

Returns:



1414
1415
1416
1417
1418
1419
# File 'complex.c', line 1414

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

#rectArray

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]

Complex#rectangular is an alias for Complex#rect.

Returns:



1414
1415
1416
1417
1418
1419
# File 'complex.c', line 1414

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

#to_cself

Returns self.

Returns:

  • (self)


1912
1913
1914
1915
1916
# File 'complex.c', line 1912

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

#to_fFloat

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

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

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

Returns:



1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
# File 'complex.c', line 1822

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(1, 0).to_i              # => 1
Complex(1, Rational(0, 1)).to_i # => 1

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

Returns:



1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
# File 'complex.c', line 1798

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_rObject

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

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

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

Related: Complex#rationalize.



1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
# File 'complex.c', line 1848

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

    if (!k_exact_zero_p(dat->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(2).to_s                      # => "2+0i"
Complex('-8/6').to_s                 # => "-4/3+0i"
Complex('1/2i').to_s                 # => "0+1/2i"
Complex(0, Float::INFINITY).to_s     # => "0+Infinity*i"
Complex(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i"

Returns:



1627
1628
1629
1630
1631
# File 'complex.c', line 1627

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