class Complex
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:
-
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#realandComplex#imaginary. -
Together, with method
Complex#rect.
The corresponding (computed) polar values may be retrieved:
-
Separately, with methods
Complex#absandComplex#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#absandComplex#arg. -
Together, with method
Complex#polar.
The corresponding (computed) rectangular values may be retrieved:
-
Separately, with methods
Complex#realandComplex#imag. -
Together, with method
Complex#rect.
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 aliasmagnitude): Returns the absolute value forself. -
arg(and its aliasesangleandphase): Returns the argument (angle) forselfin radians. -
denominator: Returns the denominator ofself. -
finite?: Returns whether bothself.realandself.imageare finite. -
hash: Returns the integer hash value forself. -
imag(and its aliasimaginary): Returns the imaginary value forself. -
infinite?: Returns whetherself.realorself.imageis infinite. -
numerator: Returns the numerator ofself. -
polar: Returns the array[self.abs, self.arg]. -
inspect: Returns a string representation ofself. -
real: Returns the real value forself. -
real?: Returnsfalse; for compatibility withNumeric#real?. -
rect(and its aliasrectangular): Returns the array[self.real, self.imag].
Comparing
-
<=>: Returns whetherselfis less than, equal to, or greater than the given argument. -
==: Returns whetherselfis equal to the given argument.
Converting
-
rationalize: Returns aRationalobject whose value is exactly or approximately equivalent to that ofself.real. -
to_c: Returnsself. -
to_d: Returns the value as aBigDecimalobject. -
to_f: Returns the value ofself.realas aFloat, if possible. -
to_i: Returns the value ofself.realas anInteger, if possible. -
to_r: Returns the value ofself.realas aRational, if possible. -
to_s: Returns a string representation ofself.
Performing Complex Arithmetic
-
*: Returns the product ofselfand the given numeric. -
**: Returnsselfraised to power of the given numeric. -
+: Returns the sum ofselfand the given numeric. -
-: Returns the difference ofselfand the given numeric. -
-@: Returns the negation ofself. -
/: Returns the quotient ofselfand the given numeric. -
abs2: Returns square of the absolute value (magnitude) forself. -
conj(and its aliasconjugate): Returns the conjugate ofself. -
fdiv: ReturnsComplex.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 fromself.
These methods are provided by the JSON gem. To make these methods available:
require 'json/add/complex'
Constants
- I
-
Equivalent to
Complex.rect(0, 1):Complex::I # => (0+1i)
Public Class Methods
Source
# File ext/json/lib/json/add/complex.rb, line 9 def self.json_create(object) Complex(object['r'], object['i']) end
See as_json.
Source
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);
}
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)
Source
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);
}
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.
Source
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);
}
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.
Public Instance Methods
Source
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, '*');
}
Returns the numeric product of self and other:
Complex.rect(9, 8) * 4 # => (36+32i) Complex.rect(20, 9) * 9.8 # => (196.0+88.2i) 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) * Rational(2, 3) # => ((6/1)+(16/3)*i)
Source
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);
}
Returns self raised to the power exponent:
Complex.rect(0, 1) ** 2 # => (-1+0i) Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i)
Source
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, '+');
}
Returns the sum of self and other:
Complex(1, 2) + 0 # => (1+2i) Complex(1, 2) + 1 # => (2+2i) Complex(1, 2) + -1 # => (0+2i) Complex(1, 2) + 1.0 # => (2.0+2i) Complex(1, 2) + Complex(2, 1) # => (3+3i) Complex(1, 2) + Complex(2.0, 1.0) # => (3.0+3.0i) Complex(1, 2) + Rational(1, 1) # => ((2/1)+2i) Complex(1, 2) + Rational(1, 2) # => ((3/2)+2i)
For a computation involving Floats, the result may be inexact (see Float#+):
Complex(1, 2) + 3.14 # => (4.140000000000001+2i)
Source
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, '-');
}
Returns the difference of self and other:
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)
Source
VALUE
rb_complex_uminus(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self),
f_negate(dat->real), f_negate(dat->imag));
}
Returns self, negated, which is the negation of each of its parts:
-Complex.rect(1, 2) # => (-1-2i) -Complex.rect(-1, -2) # => (1+2i)
Source
VALUE
rb_complex_div(VALUE self, VALUE other)
{
return f_divide(self, other, f_quo, id_quo);
}
Returns the quotient of self and other:
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)
Source
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;
}
Compares self and other.
Returns:
-
self.real <=> other.realif both of the following are true:-
self.imag == 0. -
other.imag == 0(always true ifotheris numeric but not complex).
-
-
nilotherwise.
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.
Class Complex includes module Comparable, each of whose methods uses Complex#<=> for comparison.
Source
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));
}
Returns true if self.real == object.real and self.imag == object.imag:
Complex.rect(2, 3) == Complex.rect(2.0, 3.0) # => true
Source
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);
}
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.
Source
static VALUE
nucomp_abs2(VALUE self)
{
get_dat1(self);
return f_add(f_mul(dat->real, dat->real),
f_mul(dat->imag, dat->imag));
}
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
Source
VALUE
rb_complex_arg(VALUE self)
{
get_dat1(self);
return rb_math_atan2(dat->imag, dat->real);
}
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
Source
# File ext/json/lib/json/add/complex.rb, line 29 def as_json(*) { JSON.create_id => self.class.name, 'r' => real, 'i' => imag, } end
Methods Complex#as_json and Complex.json_create may be used to serialize and deserialize a Complex object; see Marshal.
Method Complex#as_json serializes self, returning a 2-element hash representing self:
require 'json/add/complex' x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0} y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}
Method JSON.create deserializes such a hash, returning a Complex object:
Complex.json_create(x) # => (2+0i) Complex.json_create(y) # => (2.0+4i)
Returns the conjugate of self, Complex.rect(self.imag, self.real):
Complex.rect(1, 2).conj # => (1-2i)
Source
VALUE
rb_complex_conjugate(VALUE self)
{
get_dat1(self);
return f_complex_new2(CLASS_OF(self), dat->real, f_negate(dat->imag));
}
Source
static VALUE
nucomp_denominator(VALUE self)
{
get_dat1(self);
return rb_lcm(f_denominator(dat->real), f_denominator(dat->imag));
}
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.
Source
static VALUE
nucomp_fdiv(VALUE self, VALUE other)
{
return f_divide(self, other, f_fdiv, id_fdiv);
}
Returns Complex.rect(self.real/numeric, self.imag/numeric):
Complex.rect(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i)
Source
static VALUE
rb_complex_finite_p(VALUE self)
{
get_dat1(self);
return RBOOL(f_finite_p(dat->real) && f_finite_p(dat->imag));
}
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?.
Source
static VALUE
nucomp_hash(VALUE self)
{
return ST2FIX(rb_complex_hash(self));
}
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
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.
Source
VALUE
rb_complex_imag(VALUE self)
{
get_dat1(self);
return dat->imag;
}
Source
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;
}
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?.
Source
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;
}
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)"
Source
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))));
}
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: Complex#denominator.
Source
static VALUE
nucomp_polar(VALUE self)
{
return rb_assoc_new(f_abs(self), f_arg(self));
}
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]
Source
VALUE
rb_complex_div(VALUE self, VALUE other)
{
return f_divide(self, other, f_quo, id_quo);
}
Returns the quotient of self and other:
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)
Source
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);
}
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: Complex#to_r.
Source
VALUE
rb_complex_real(VALUE self)
{
get_dat1(self);
return dat->real;
}
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.
Source
static VALUE
nucomp_real_p_m(VALUE self)
{
return Qfalse;
}
Returns false; for compatibility with Numeric#real?.
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.
Source
static VALUE
nucomp_rect(VALUE self)
{
get_dat1(self);
return rb_assoc_new(dat->real, dat->imag);
}
Source
# File bundled-src/bigdecimal-4.0.1/lib/bigdecimal/util.rb, line 164 def to_d(precision=0) BigDecimal(self) unless self.imag.zero? # to raise error BigDecimal(self.real, precision) end
Returns the value as a BigDecimal. If the imaginary part is not 0, an error is raised
The precision parameter is used to determine the number of significant digits for the result. When precision is set to 0, the number of digits to represent the float being converted is determined automatically. The default precision is 0.
require 'bigdecimal' require 'bigdecimal/util' Complex(0.1234567, 0).to_d(4) # => 0.1235e0 Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 Complex(1, 1).to_d # raises ArgumentError
See also Kernel.BigDecimal.
Source
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);
}
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)).
Source
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);
}
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)).
Source
# File ext/json/lib/json/add/complex.rb, line 48 def to_json(*args) as_json.to_json(*args) end
Returns a JSON string representing self:
require 'json/add/complex' puts Complex(2).to_json puts Complex(2.0, 4).to_json
Output:
{"json_class":"Complex","r":2,"i":0}
{"json_class":"Complex","r":2.0,"i":4}
Source
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);
}
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: Complex#rationalize.
Source
static VALUE
nucomp_to_s(VALUE self)
{
return f_format(self, rb_usascii_str_new2(""), rb_String);
}
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"