26 Numerics library [numerics]

26.4 Complex numbers [complex.numbers]

The header <complex> defines a class template, and numerous functions for representing and manipulating complex numbers.

The effect of instantiating the template complex for any type other than float, double, or long double is unspecified. The specializations complex<float>, complex<double>, and complex<long double> are literal types ([basic.types]).

If the result of a function is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.

If z is an lvalue expression of type cv std::complex<T> then:

  • the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,

  • reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z, and

  • reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z.

Moreover, if a is an expression of type cv std::complex<T>* and the expression a[i] is well-defined for an integer expression i, then:

  • reinterpret_cast<cv T*>(a)[2*i] shall designate the real part of a[i], and

  • reinterpret_cast<cv T*>(a)[2*i + 1] shall designate the imaginary part of a[i].

26.4.1 Header <complex> synopsis [complex.syn]

namespace std {
  template<class T> class complex;
  template<> class complex<float>;
  template<> class complex<double>;
  template<> class complex<long double>;

  // [complex.ops], operators:
  template<class T>
    complex<T> operator+(const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator+(const complex<T>&, const T&);
  template<class T> complex<T> operator+(const T&, const complex<T>&);

  template<class T> complex<T> operator-(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&, const T&);
  template<class T> complex<T> operator-(const T&, const complex<T>&);

  template<class T> complex<T> operator*(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator*(const complex<T>&, const T&);
  template<class T> complex<T> operator*(const T&, const complex<T>&);

  template<class T> complex<T> operator/(
    const complex<T>&, const complex<T>&);
  template<class T> complex<T> operator/(const complex<T>&, const T&);
  template<class T> complex<T> operator/(const T&, const complex<T>&);

  template<class T> complex<T> operator+(const complex<T>&);
  template<class T> complex<T> operator-(const complex<T>&);

  template<class T> bool operator==(
    const complex<T>&, const complex<T>&);
  template<class T> bool operator==(const complex<T>&, const T&);
  template<class T> bool operator==(const T&, const complex<T>&);

  template<class T> bool operator!=(const complex<T>&, const complex<T>&);
  template<class T> bool operator!=(const complex<T>&, const T&);
  template<class T> bool operator!=(const T&, const complex<T>&);

  template<class T, class charT, class traits>
  basic_istream<charT, traits>&
  operator>>(basic_istream<charT, traits>&, complex<T>&);

  template<class T, class charT, class traits>
  basic_ostream<charT, traits>&
  operator<<(basic_ostream<charT, traits>&, const complex<T>&);

  // [complex.value.ops], values:
  template<class T> T real(const complex<T>&);
  template<class T> T imag(const complex<T>&);

  template<class T> T abs(const complex<T>&);
  template<class T> T arg(const complex<T>&);
  template<class T> T norm(const complex<T>&);

  template<class T> complex<T> conj(const complex<T>&);
  template <class T> complex<T> proj(const complex<T>&);
  template<class T> complex<T> polar(const T&, const T& = 0);

  // [complex.transcendentals], transcendentals:
  template<class T> complex<T> acos(const complex<T>&);
  template<class T> complex<T> asin(const complex<T>&);
  template<class T> complex<T> atan(const complex<T>&);

  template<class T> complex<T> acosh(const complex<T>&);
  template<class T> complex<T> asinh(const complex<T>&);
  template<class T> complex<T> atanh(const complex<T>&);

  template<class T> complex<T> cos  (const complex<T>&);
  template<class T> complex<T> cosh (const complex<T>&);
  template<class T> complex<T> exp  (const complex<T>&);
  template<class T> complex<T> log  (const complex<T>&);
  template<class T> complex<T> log10(const complex<T>&);

  template<class T> complex<T> pow(const complex<T>&, const T&);
  template<class T> complex<T> pow(const complex<T>&, const complex<T>&);
  template<class T> complex<T> pow(const T&, const complex<T>&);

  template<class T> complex<T> sin  (const complex<T>&);
  template<class T> complex<T> sinh (const complex<T>&);
  template<class T> complex<T> sqrt (const complex<T>&);
  template<class T> complex<T> tan  (const complex<T>&);
  template<class T> complex<T> tanh (const complex<T>&);
}

26.4.2 Class template complex [complex]

namespace std {
  template<class T>
  class complex {
  public:
    typedef T value_type;

    complex(const T& re = T(), const T& im = T());
    complex(const complex&);
    template<class X> complex(const complex<X>&);

    T real() const;
    void real(T);
    T imag() const;
    void imag(T);

    complex<T>& operator= (const T&);
    complex<T>& operator+=(const T&);
    complex<T>& operator-=(const T&);
    complex<T>& operator*=(const T&);
    complex<T>& operator/=(const T&);

    complex& operator=(const complex&);
    template<class X> complex<T>& operator= (const complex<X>&);
    template<class X> complex<T>& operator+=(const complex<X>&);
    template<class X> complex<T>& operator-=(const complex<X>&);
    template<class X> complex<T>& operator*=(const complex<X>&);
    template<class X> complex<T>& operator/=(const complex<X>&);
  };
}

The class complex describes an object that can store the Cartesian components, real() and imag(), of a complex number.

26.4.3 complex specializations [complex.special]

namespace std {
  template<> class complex<float> {
  public:
    typedef float value_type;

    constexpr complex(float re = 0.0f, float im = 0.0f);
    explicit constexpr complex(const complex<double>&);
    explicit constexpr complex(const complex<long double>&);

    constexpr float real();
    void real(float);
    constexpr float imag();
    void imag(float);

    complex<float>& operator= (float);
    complex<float>& operator+=(float);
    complex<float>& operator-=(float);
    complex<float>& operator*=(float);
    complex<float>& operator/=(float);

    complex<float>& operator=(const complex<float>&);
    template<class X> complex<float>& operator= (const complex<X>&);
    template<class X> complex<float>& operator+=(const complex<X>&);
    template<class X> complex<float>& operator-=(const complex<X>&);
    template<class X> complex<float>& operator*=(const complex<X>&);
    template<class X> complex<float>& operator/=(const complex<X>&);
  };

  template<> class complex<double> {
  public:
    typedef double value_type;

    constexpr complex(double re = 0.0, double im = 0.0);
    constexpr complex(const complex<float>&);
    explicit constexpr complex(const complex<long double>&);

    constexpr double real();
    void real(double);
    constexpr double imag();
    void imag(double);

    complex<double>& operator= (double);
    complex<double>& operator+=(double);
    complex<double>& operator-=(double);
    complex<double>& operator*=(double);
    complex<double>& operator/=(double);

    complex<double>& operator=(const complex<double>&);
    template<class X> complex<double>& operator= (const complex<X>&);
    template<class X> complex<double>& operator+=(const complex<X>&);
    template<class X> complex<double>& operator-=(const complex<X>&);
    template<class X> complex<double>& operator*=(const complex<X>&);
    template<class X> complex<double>& operator/=(const complex<X>&);
  };

  template<> class complex<long double> {
  public:
    typedef long double value_type;

    constexpr complex(long double re = 0.0L, long double im = 0.0L);
    constexpr complex(const complex<float>&);
    constexpr complex(const complex<double>&);

    constexpr long double real();
    void real(long double);
    constexpr long double imag();
    void imag(long double);

    complex<long double>& operator=(const complex<long double>&);
    complex<long double>& operator= (long double);
    complex<long double>& operator+=(long double);
    complex<long double>& operator-=(long double);
    complex<long double>& operator*=(long double);
    complex<long double>& operator/=(long double);

    template<class X> complex<long double>& operator= (const complex<X>&);
    template<class X> complex<long double>& operator+=(const complex<X>&);
    template<class X> complex<long double>& operator-=(const complex<X>&);
    template<class X> complex<long double>& operator*=(const complex<X>&);
    template<class X> complex<long double>& operator/=(const complex<X>&);
  };
}

26.4.4 complex member functions [complex.members]

template<class T> complex(const T& re = T(), const T& im = T());

Effects: Constructs an object of class complex.

Postcondition: real() == re && imag() == im.

T real() const;

Returns: The value of the real component.

void real(T val);

Effects: Assigns val to the real component.

T imag() const;

Returns: The value of the imaginary component.

void imag(T val);

Effects: Assigns val to the imaginary component.

26.4.5 complex member operators [complex.member.ops]

complex<T>& operator+=(const T& rhs);

Effects: Adds the scalar value rhs to the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.

Returns: *this.

complex<T>& operator-=(const T& rhs);

Effects: Subtracts the scalar value rhs from the real part of the complex value *this and stores the result in the real part of *this, leaving the imaginary part unchanged.

Returns: *this.

complex<T>& operator*=(const T& rhs);

Effects: Multiplies the scalar value rhs by the complex value *this and stores the result in *this.

Returns: *this.

complex<T>& operator/=(const T& rhs);

Effects: Divides the scalar value rhs into the complex value *this and stores the result in *this.

Returns: *this.

complex<T>& operator+=(const complex<T>& rhs);

Effects: Adds the complex value rhs to the complex value *this and stores the sum in *this.

Returns: *this.

complex<T>& operator-=(const complex<T>& rhs);

Effects: Subtracts the complex value rhs from the complex value *this and stores the difference in *this.

Returns: *this.

complex<T>& operator*=(const complex<T>& rhs);

Effects: Multiplies the complex value rhs by the complex value *this and stores the product in *this.

Returns: *this.

complex<T>& operator/=(const complex<T>& rhs);

Effects: Divides the complex value rhs into the complex value *this and stores the quotient in *this.

Returns: *this.

26.4.6 complex non-member operations [complex.ops]

template<class T> complex<T> operator+(const complex<T>& lhs);

Remarks: unary operator.

Returns: complex<T>(lhs).

template<class T>
  complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs);
template<class T> complex<T> operator+(const complex<T>& lhs, const T& rhs);
template<class T> complex<T> operator+(const T& lhs, const complex<T>& rhs);

Returns: complex<T>(lhs) += rhs.

template<class T> complex<T> operator-(const complex<T>& lhs);

Remarks: unary operator.

Returns: complex<T>(-lhs.real(),-lhs.imag()).

template<class T> complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator-(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator-(const T& lhs, const complex<T>& rhs);

Returns: complex<T>(lhs) -= rhs.

template<class T> complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator*(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator*(const T& lhs, const complex<T>& rhs);

Returns: complex<T>(lhs) *= rhs.

template<class T> complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs); template<class T> complex<T> operator/(const complex<T>& lhs, const T& rhs); template<class T> complex<T> operator/(const T& lhs, const complex<T>& rhs);

Returns: complex<T>(lhs) /= rhs.

template<class T> bool operator==(const complex<T>& lhs, const complex<T>& rhs); template<class T> bool operator==(const complex<T>& lhs, const T& rhs); template<class T> bool operator==(const T& lhs, const complex<T>& rhs);

Returns: lhs.real() == rhs.real() && lhs.imag() == rhs.imag().

Remarks: The imaginary part is assumed to be T(), or 0.0, for the T arguments.

template<class T> bool operator!=(const complex<T>& lhs, const complex<T>& rhs); template<class T> bool operator!=(const complex<T>& lhs, const T& rhs); template<class T> bool operator!=(const T& lhs, const complex<T>& rhs);

Returns: rhs.real() != lhs.real() || rhs.imag() != lhs.imag().

template<class T, class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, complex<T>& x);

Effects: Extracts a complex number x of the form: u, (u), or (u,v), where u is the real part and v is the imaginary part ([istream.formatted]).

Requires: The input values shall be convertible to T.

If bad input is encountered, calls is.setstate(ios_base::failbit) (which may throw ios::failure ([iostate.flags])).

Returns: is.

Remarks: This extraction is performed as a series of simpler extractions. Therefore, the skipping of whitespace is specified to be the same for each of the simpler extractions.

template<class T, class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);

Effects: inserts the complex number x onto the stream o as if it were implemented as follows:

template<class T, class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& o, const complex<T>& x) {
  basic_ostringstream<charT, traits> s;
  s.flags(o.flags());
  s.imbue(o.getloc());
  s.precision(o.precision());
  s << '(' << x.real() << "," << x.imag() << ')';
  return o << s.str();
}

Note: In a locale in which comma is used as a decimal point character, the use of comma as a field separator can be ambiguous. Inserting std::showpoint into the output stream forces all outputs to show an explicit decimal point character; as a result, all inserted sequences of complex numbers can be extracted unambiguously.

26.4.7 complex value operations [complex.value.ops]

template<class T> T real(const complex<T>& x);

Returns: x.real().

template<class T> T imag(const complex<T>& x);

Returns: x.imag().

template<class T> T abs(const complex<T>& x);

Returns: The magnitude of x.

template<class T> T arg(const complex<T>& x);

Returns: The phase angle of x, or atan2(imag(x), real(x)).

template<class T> T norm(const complex<T>& x);

Returns: The squared magnitude of x.

template<class T> complex<T> conj(const complex<T>& x);

Returns: The complex conjugate of x.

template<class T> complex<T> proj(const complex<T>& x);

Returns: The projection of x onto the Riemann sphere.

Remarks: Behaves the same as the C function cproj, defined in 7.3.9.4.

template<class T> complex<T> polar(const T& rho, const T& theta = 0);

Returns: The complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta.

26.4.8 complex transcendentals [complex.transcendentals]

template<class T> complex<T> acos(const complex<T>& x);

Returns: The complex arc cosine of x.

Remarks: Behaves the same as C function cacos, defined in 7.3.5.1.

template<class T> complex<T> asin(const complex<T>& x);

Returns: The complex arc sine of x.

Remarks: Behaves the same as C function casin, defined in 7.3.5.2.

template<class T> complex<T> atan(const complex<T>& x);

Returns: The complex arc tangent of x.

Remarks: Behaves the same as C function catan, defined in 7.3.5.3.

template<class T> complex<T> acosh(const complex<T>& x);

Returns: The complex arc hyperbolic cosine of x.

Remarks: Behaves the same as C function cacosh, defined in 7.3.6.1.

template<class T> complex<T> asinh(const complex<T>& x);

Returns: The complex arc hyperbolic sine of x.

Remarks: Behaves the same as C function casinh, defined in 7.3.6.2.

template<class T> complex<T> atanh(const complex<T>& x);

Returns: The complex arc hyperbolic tangent of x.

Remarks: Behaves the same as C function catanh, defined in 7.3.6.3.

template<class T> complex<T> cos(const complex<T>& x);

Returns: The complex cosine of x.

template<class T> complex<T> cosh(const complex<T>& x);

Returns: The complex hyperbolic cosine of x.

template<class T> complex<T> exp(const complex<T>& x);

Returns: The complex base e exponential of x.

template<class T> complex<T> log(const complex<T>& x);

Remarks: the branch cuts are along the negative real axis.

Returns: The complex natural (base e) logarithm of x, in the range of a strip mathematically unbounded along the real axis and in the interval [-i times pi,i times pi] along the imaginary axis. When x is a negative real number, imag(log(x)) is pi.

template<class T> complex<T> log10(const complex<T>& x);

Remarks: the branch cuts are along the negative real axis.

Returns: The complex common (base 10) logarithm of x, defined as log(x)/log(10).

template<class T> complex<T> pow(const complex<T>& x, const complex<T>& y); template<class T> complex<T> pow (const complex<T>& x, const T& y); template<class T> complex<T> pow (const T& x, const complex<T>& y);

Remarks: the branch cuts are along the negative real axis.

Returns: The complex power of base x raised to the y-th power, defined as exp(y*log(x)). The value returned for pow(0,0) is implementation-defined.

template<class T> complex<T> sin (const complex<T>& x);

Returns: The complex sine of x.

template<class T> complex<T> sinh (const complex<T>& x);

Returns: The complex hyperbolic sine of x.

template<class T> complex<T> sqrt (const complex<T>& x);

Remarks: the branch cuts are along the negative real axis.

Returns: The complex square root of x, in the range of the right half-plane. If the argument is a negative real number, the value returned lies on the positive imaginary axis.

template<class T> complex<T> tan (const complex<T>& x);

Returns: The complex tangent of x.

template<class T> complex<T> tanh (const complex<T>& x);

Returns: The complex hyperbolic tangent of x.

26.4.9 Additional overloads [cmplx.over]

The following function templates shall have additional overloads:

arg                   norm 
conj                  proj
imag                  real 

The additional overloads shall be sufficient to ensure:

  1. If the argument has type long double, then it is effectively cast to complex<long double>.

  2. Otherwise, if the argument has type double or an integer type, then it is effectively cast to complex<double>.

  3. Otherwise, if the argument has type float, then it is effectively cast to complex<float>.

Function template pow shall have additional overloads sufficient to ensure, for a call with at least one argument of type complex<T>:

  1. If either argument has type complex<long double> or type long double, then both arguments are effectively cast to complex<long double>.

  2. Otherwise, if either argument has type complex<double>, double, or an integer type, then both arguments are effectively cast to complex<double>.

  3. Otherwise, if either argument has type complex<float> or float, then both arguments are effectively cast to complex<float>.

26.4.10 Header <ccomplex> [ccmplx]

The header behaves as if it simply includes the header <complex>.