Class: Complex

Inherits:
Numeric show all
Defined in:
complex.c

Overview

A complex number can be represented as a paired real number with imaginary unit; a+bi. Where a is real part, b is imaginary part and i is imaginary unit. Real a equals complex a+0i mathematically.

Complex object can be created as literal, and also by using Kernel#Complex, Complex::rect, Complex::polar or to_c method.

2+1i                 #=> (2+1i)
Complex(1)           #=> (1+0i)
Complex(2, 3)        #=> (2+3i)
Complex.polar(2, 3)  #=> (-1.9799849932008908+0.2822400161197344i)
3.to_c               #=> (3+0i)

You can also create complex object from floating-point numbers or strings.

Complex(0.3)         #=> (0.3+0i)
Complex('0.3-0.5i')  #=> (0.3-0.5i)
Complex('2/3+3/4i')  #=> ((2/3)+(3/4)*i)
Complex('1@2')       #=> (-0.4161468365471424+0.9092974268256817i)

0.3.to_c             #=> (0.3+0i)
'0.3-0.5i'.to_c      #=> (0.3-0.5i)
'2/3+3/4i'.to_c      #=> ((2/3)+(3/4)*i)
'1@2'.to_c           #=> (-0.4161468365471424+0.9092974268256817i)

A complex object is either an exact or an inexact number.

Complex(1, 1) / 2    #=> ((1/2)+(1/2)*i)
Complex(1, 1) / 2.0  #=> (0.5+0.5i)

Defined Under Namespace

Classes: compatible

Constant Summary collapse

I =

The imaginary unit.

f_complex_new_bang2(rb_cComplex, ZERO, ONE)

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Numeric

#%, #+@, #ceil, #clone, #div, #divmod, #dup, #floor, #i, #integer?, #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]) ⇒ Object

Returns a complex object which denotes the given polar form.

Complex.polar(3, 0)            #=> (3.0+0.0i)
Complex.polar(3, Math::PI/2)   #=> (1.836909530733566e-16+3.0i)
Complex.polar(3, Math::PI)     #=> (-3.0+3.673819061467132e-16i)
Complex.polar(3, -Math::PI/2)  #=> (1.836909530733566e-16-3.0i)


700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'complex.c', line 700

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

    switch (rb_scan_args(argc, argv, "11", &abs, &arg)) {
      case 1:
	nucomp_real_check(abs);
	return nucomp_s_new_internal(klass, abs, ZERO);
      default:
	nucomp_real_check(abs);
	nucomp_real_check(arg);
	break;
    }
    if (RB_TYPE_P(abs, T_COMPLEX)) {
        get_dat1(abs);
        abs = dat->real;
    }
    if (RB_TYPE_P(arg, T_COMPLEX)) {
        get_dat1(arg);
        arg = dat->real;
    }
    return f_complex_polar(klass, abs, arg);
}

.rect(real[, imag]) ⇒ Object .rectangular(real[, imag]) ⇒ Object

Returns a complex object which denotes the given rectangular form.

Complex.rectangular(1, 2)  #=> (1+2i)


484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'complex.c', line 484

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:
	nucomp_real_check(real);
	imag = ZERO;
	break;
      default:
	nucomp_real_check(real);
	nucomp_real_check(imag);
	break;
    }

    return nucomp_s_canonicalize_internal(klass, real, imag);
}

.rect(real[, imag]) ⇒ Object .rectangular(real[, imag]) ⇒ Object

Returns a complex object which denotes the given rectangular form.

Complex.rectangular(1, 2)  #=> (1+2i)


484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'complex.c', line 484

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:
	nucomp_real_check(real);
	imag = ZERO;
	break;
      default:
	nucomp_real_check(real);
	nucomp_real_check(imag);
	break;
    }

    return nucomp_s_canonicalize_internal(klass, real, imag);
}

Instance Method Details

#*(numeric) ⇒ Object

Performs multiplication.

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)


880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
# File 'complex.c', line 880

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

Performs exponentiation.

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


993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
# File 'complex.c', line 993

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 (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_TYPE_P(other, T_BIGNUM))
	    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

Performs addition.

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)


786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
# File 'complex.c', line 786

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

Performs subtraction.

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)


820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
# File 'complex.c', line 820

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 negation of the value.

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


766
767
768
769
770
771
772
# File 'complex.c', line 766

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 #quo(numeric) ⇒ Object

Performs division.

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)


956
957
958
959
960
# File 'complex.c', line 956

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

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

If cmp‘s imaginary part is zero, and object is also a real number (or a Complex number where the imaginary part is zero), compare the real part of cmp to object. Otherwise, return nil.

Complex(2, 3)  <=> Complex(2, 3)   #=> nil
Complex(2, 3)  <=> 1               #=> nil
Complex(2)     <=> 1               #=> 1
Complex(2)     <=> 2               #=> 0
Complex(2)     <=> 3               #=> -1

Returns:

  • (0, 1, -1, nil)


1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
# File 'complex.c', line 1129

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

#==(object) ⇒ Boolean

Returns true if cmp equals object numerically.

Complex(2, 3)  == Complex(2, 3)   #=> true
Complex(5)     == 5               #=> true
Complex(0)     == 0.0             #=> true
Complex('1/3') == 0.33            #=> false
Complex('1/2') == '1/2'           #=> false

Returns:

  • (Boolean)


1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'complex.c', line 1091

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

	return f_boolcast(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 f_boolcast(f_eqeq_p(dat->real, other) && f_zero_p(dat->imag));
    }
    return f_boolcast(f_eqeq_p(other, self));
}

#absObject #magnitudeObject

Returns the absolute part of its polar form.

Complex(-1).abs         #=> 1
Complex(3.0, -4.0).abs  #=> 5.0


1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
# File 'complex.c', line 1169

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

#abs2Object

Returns square of the absolute value.

Complex(-1).abs2         #=> 1
Complex(3.0, -4.0).abs2  #=> 25.0


1198
1199
1200
1201
1202
1203
1204
# File 'complex.c', line 1198

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

Returns the angle part of its polar form.

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

Overloads:



1216
1217
1218
1219
1220
1221
# File 'complex.c', line 1216

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

#argFloat #angleFloat #phaseFloat

Returns the angle part of its polar form.

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

Overloads:



1216
1217
1218
1219
1220
1221
# File 'complex.c', line 1216

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

#coerce(other) ⇒ Object

:nodoc:



1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
# File 'complex.c', line 1146

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

Returns the complex conjugate.

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


1262
1263
1264
1265
1266
1267
# File 'complex.c', line 1262

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

#conjObject #conjugateObject

Returns the complex conjugate.

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


1262
1263
1264
1265
1266
1267
# File 'complex.c', line 1262

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 (lcm of both denominator - real and imag).

See numerator.

Returns:



1290
1291
1292
1293
1294
1295
# File 'complex.c', line 1290

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)


1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
# File 'complex.c', line 1347

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

	return f_boolcast((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

Performs division as each part is a float, never returns a float.

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


972
973
974
975
976
# File 'complex.c', line 972

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

#finite?Boolean

Returns true if cmp‘s real and imaginary parts are both finite numbers, otherwise returns false.

Returns:

  • (Boolean)


1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
# File 'complex.c', line 1449

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

    if (f_finite_p(dat->real) && f_finite_p(dat->imag)) {
	return Qtrue;
    }
    return Qfalse;
}

#hashObject

:nodoc:



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

static VALUE
nucomp_hash(VALUE self)
{
    st_index_t v, h[2];
    VALUE n;

    get_dat1(self);
    n = rb_hash(dat->real);
    h[0] = NUM2LONG(n);
    n = rb_hash(dat->imag);
    h[1] = NUM2LONG(n);
    v = rb_memhash(h, sizeof(h));
    return ST2FIX(v);
}

#imagObject #imaginaryObject

Returns the imaginary part.

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


751
752
753
754
755
756
# File 'complex.c', line 751

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

#imagObject #imaginaryObject

Returns the imaginary part.

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


751
752
753
754
755
756
# File 'complex.c', line 751

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

#infinite?nil, 1

Returns 1 if cmp‘s real or imaginary part is an infinite number, otherwise returns nil.

For example:

   (1+1i).infinite?                   #=> nil
   (Float::INFINITY + 1i).infinite?   #=> 1

Returns:

  • (nil, 1)


1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
# File 'complex.c', line 1472

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

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

#inspectString

Returns the value as a string for inspection.

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:



1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
# File 'complex.c', line 1428

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

#absObject #magnitudeObject

Returns the absolute part of its polar form.

Complex(-1).abs         #=> 1
Complex(3.0, -4.0).abs  #=> 5.0


1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
# File 'complex.c', line 1169

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:



1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
# File 'complex.c', line 1504

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

#numeratorNumeric

Returns the numerator.

    1   2       3+4i  <-  numerator
    - + -i  ->  ----
    2   3        6    <-  denominator

c = Complex('1/2+2/3i')  #=> ((1/2)+(2/3)*i)
n = c.numerator          #=> (3+4i)
d = c.denominator        #=> 6
n / d                    #=> ((1/2)+(2/3)*i)
Complex(Rational(n.real, d), Rational(n.imag, d))
                         #=> ((1/2)+(2/3)*i)

See denominator.

Returns:



1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
# File 'complex.c', line 1315

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 #angleFloat #phaseFloat

Returns the angle part of its polar form.

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

Overloads:



1216
1217
1218
1219
1220
1221
# File 'complex.c', line 1216

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

#polarArray

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

Complex(1, 2).polar  #=> [2.23606797749979, 1.1071487177940904]

Returns:



1247
1248
1249
1250
1251
# File 'complex.c', line 1247

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

#quoObject

#rationalize([eps]) ⇒ Object

Returns the value as a rational if possible (the imaginary part should be exactly zero).

Complex(1.0/3, 0).rationalize  #=> (1/3)
Complex(1, 0.0).rationalize    # RangeError
Complex(1, 2).rationalize      # RangeError

See to_r.



1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
# File 'complex.c', line 1659

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

#realObject

Returns the real part.

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


734
735
736
737
738
739
# File 'complex.c', line 734

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

#Complex(1) ⇒ false #Complex(1, 2) ⇒ false

Returns false, even if the complex number has no imaginary part.

Overloads:

  • #Complex(1) ⇒ false

    Returns:

    • (false)
  • #Complex(1, 2) ⇒ false

    Returns:

    • (false)


1276
1277
1278
1279
1280
# File 'complex.c', line 1276

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

#rectArray #rectangularArray

Returns an array; [cmp.real, cmp.imag].

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

Overloads:



1232
1233
1234
1235
1236
1237
# File 'complex.c', line 1232

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

#rectArray #rectangularArray

Returns an array; [cmp.real, cmp.imag].

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

Overloads:



1232
1233
1234
1235
1236
1237
# File 'complex.c', line 1232

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

#to_cself

Returns self.

Complex(2).to_c      #=> (2+0i)
Complex(-8, 6).to_c  #=> (-8+6i)

Returns:

  • (self)


1682
1683
1684
1685
1686
# File 'complex.c', line 1682

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

#to_fFloat

Returns the value as a float if possible (the imaginary part should be exactly zero).

Complex(1, 0).to_f    #=> 1.0
Complex(1, 0.0).to_f  # RangeError
Complex(1, 2).to_f    # RangeError

Returns:



1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
# File 'complex.c', line 1609

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 as an integer if possible (the imaginary part should be exactly zero).

Complex(1, 0).to_i    #=> 1
Complex(1, 0.0).to_i  # RangeError
Complex(1, 2).to_i    # RangeError

Returns:



1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
# File 'complex.c', line 1586

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 as a rational if possible (the imaginary part should be exactly zero).

Complex(1, 0).to_r    #=> (1/1)
Complex(1, 0.0).to_r  # RangeError
Complex(1, 2).to_r    # RangeError

See rationalize.



1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
# File 'complex.c', line 1634

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 the value as a string.

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:



1410
1411
1412
1413
1414
# File 'complex.c', line 1410

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