24 Numerics library [numerics]

24.5 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.
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 of type cv 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 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].

24.5.1 Header <complex> synopsis [complex.syn]

namespace std {
  // [complex], class template complex
  template<class T> class complex;

  // [complex.special], complex specializations
  template<> class complex<float>;
  template<> class complex<double>;
  template<> class complex<long double>;

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

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

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

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

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

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

  template<class T> constexpr bool operator!=(const complex<T>&, const complex<T>&);
  template<class T> constexpr bool operator!=(const complex<T>&, const T&);
  template<class T> constexpr 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> constexpr T real(const complex<T>&);
  template<class T> constexpr T imag(const complex<T>&);

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

  template<class T> constexpr 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& = T());

  // [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>&);

  // [complex.literals], complex literals
  inline namespace literals {
  inline namespace complex_literals {
    constexpr complex<long double> operator""il(long double);
    constexpr complex<long double> operator""il(unsigned long long);
    constexpr complex<double> operator""i(long double);
    constexpr complex<double> operator""i(unsigned long long);
    constexpr complex<float> operator""if(long double);
    constexpr complex<float> operator""if(unsigned long long);
  }
  }
}

24.5.2 Class template complex [complex]

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

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

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

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

    constexpr complex& operator=(const complex&);
    template<class X> constexpr complex& operator= (const complex<X>&);
    template<class X> constexpr complex& operator+=(const complex<X>&);
    template<class X> constexpr complex& operator-=(const complex<X>&);
    template<class X> constexpr complex& operator*=(const complex<X>&);
    template<class X> constexpr complex& operator/=(const complex<X>&);
  };
}
The class complex describes an object that can store the Cartesian components, real() and imag(), of a complex number.

24.5.3 complex specializations [complex.special]

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

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

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

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

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

  template<> class complex<double> {
  public:
    using value_type = double;

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

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

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

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

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

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

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

    constexpr complex& operator= (long double);
    constexpr complex& operator+=(long double);
    constexpr complex& operator-=(long double);
    constexpr complex& operator*=(long double);
    constexpr complex& operator/=(long double);

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

24.5.4 complex member functions [complex.members]

template<class T> constexpr complex(const T& re = T(), const T& im = T());
Effects: Constructs an object of class complex.
Ensures: real() == re && imag() == im.
constexpr T real() const;
Returns: The value of the real component.
constexpr void real(T val);
Effects: Assigns val to the real component.
constexpr T imag() const;
Returns: The value of the imaginary component.
constexpr void imag(T val);
Effects: Assigns val to the imaginary component.

24.5.5 complex member operators [complex.member.ops]

constexpr complex& 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.
constexpr complex& 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.
constexpr complex& operator*=(const T& rhs);
Effects: Multiplies the scalar value rhs by the complex value *this and stores the result in *this.
Returns: *this.
constexpr complex& operator/=(const T& rhs);
Effects: Divides the scalar value rhs into the complex value *this and stores the result in *this.
Returns: *this.
template<class X> constexpr complex& operator+=(const complex<X>& rhs);
Effects: Adds the complex value rhs to the complex value *this and stores the sum in *this.
Returns: *this.
template<class X> constexpr complex& operator-=(const complex<X>& rhs);
Effects: Subtracts the complex value rhs from the complex value *this and stores the difference in *this.
Returns: *this.
template<class X> constexpr complex& operator*=(const complex<X>& rhs);
Effects: Multiplies the complex value rhs by the complex value *this and stores the product in *this.
Returns: *this.
template<class X> constexpr complex& operator/=(const complex<X>& rhs);
Effects: Divides the complex value rhs into the complex value *this and stores the quotient in *this.
Returns: *this.

24.5.6 complex non-member operations [complex.ops]

template<class T> constexpr complex<T> operator+(const complex<T>& lhs);
Returns: complex<T>(lhs).
Remarks: unary operator.
template<class T> constexpr complex<T> operator+(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr complex<T> operator+(const complex<T>& lhs, const T& rhs); template<class T> constexpr complex<T> operator+(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) += rhs.
template<class T> constexpr complex<T> operator-(const complex<T>& lhs);
Returns: complex<T>(-lhs.real(),-lhs.imag()).
Remarks: unary operator.
template<class T> constexpr complex<T> operator-(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr complex<T> operator-(const complex<T>& lhs, const T& rhs); template<class T> constexpr complex<T> operator-(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) -= rhs.
template<class T> constexpr complex<T> operator*(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr complex<T> operator*(const complex<T>& lhs, const T& rhs); template<class T> constexpr complex<T> operator*(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) *= rhs.
template<class T> constexpr complex<T> operator/(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr complex<T> operator/(const complex<T>& lhs, const T& rhs); template<class T> constexpr complex<T> operator/(const T& lhs, const complex<T>& rhs);
Returns: complex<T>(lhs) /= rhs.
template<class T> constexpr bool operator==(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr bool operator==(const complex<T>& lhs, const T& rhs); template<class T> constexpr 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> constexpr bool operator!=(const complex<T>& lhs, const complex<T>& rhs); template<class T> constexpr bool operator!=(const complex<T>& lhs, const T& rhs); template<class T> constexpr 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);
Requires: The input values shall be convertible to T.
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]).
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:
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 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.
end note
]

24.5.7 complex value operations [complex.value.ops]

template<class T> constexpr T real(const complex<T>& x);
Returns: x.real().
template<class T> constexpr 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> constexpr T norm(const complex<T>& x);
Returns: The squared magnitude of x.
template<class T> constexpr 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.
See also: ISO C 7.3.9.5
template<class T> complex<T> polar(const T& rho, const T& theta = T());
Requires: rho shall be non-negative and non-NaN.
theta shall be finite.
Returns: The complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta.

24.5.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 the C function cacos.
See also: ISO C 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 the C function casin.
See also: ISO C 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 the C function catan.
See also: ISO C 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 the C function cacosh.
See also: ISO C 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 the C function casinh.
See also: ISO C 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 the C function catanh.
See also: ISO C 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);
Returns: The complex natural (base-e) logarithm of x.
For all x, imag(log(x)) lies in the interval [, π].
[Note
:
The semantics of this function are intended to be the same in C++ as they are for clog in C.
end note
]
Remarks: The branch cuts are along the negative real axis.
template<class T> complex<T> log10(const complex<T>& x);
Returns: The complex common (base-10) logarithm of x, defined as log(x) / log(10).
Remarks: The branch cuts are along the negative real axis.
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);
Returns: The complex power of base x raised to the y power, defined as exp(y * log(x)).
The value returned for pow(0, 0) is implementation-defined.
Remarks: The branch cuts are along the negative real axis.
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);
Returns: The complex square root of x, in the range of the right half-plane.
[Note
:
The semantics of this function are intended to be the same in C++ as they are for csqrt in C.
end note
]
Remarks: The branch cuts are along the negative real 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.

24.5.9 Additional overloads [cmplx.over]

The following function templates shall have additional overloads:
arg                   norm
conj                  proj
imag                  real
where norm, conj, imag, and real are constexpr overloads.
The additional overloads shall be sufficient to ensure:
  • If the argument has type long double, then it is effectively cast to complex<long double>.
  • Otherwise, if the argument has type double or an integer type, then it is effectively cast to complex<​double>.
  • 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>:
  • If either argument has type complex<long double> or type long double, then both arguments are effectively cast to complex<long double>.
  • Otherwise, if either argument has type complex<double>, double, or an integer type, then both arguments are effectively cast to complex<double>.
  • Otherwise, if either argument has type complex<float> or float, then both arguments are effectively cast to complex<float>.

24.5.10 Suffixes for complex number literals [complex.literals]

This subclause describes literal suffixes for constructing complex number literals.
The suffixes i, il, and if create complex numbers of the types complex<double>, complex<long double>, and complex<float> respectively, with their imaginary part denoted by the given literal number and the real part being zero.
constexpr complex<long double> operator""il(long double d); constexpr complex<long double> operator""il(unsigned long long d);
Returns: complex<long double>{0.0L, static_­cast<long double>(d)}.
constexpr complex<double> operator""i(long double d); constexpr complex<double> operator""i(unsigned long long d);
Returns: complex<double>{0.0, static_­cast<double>(d)}.
constexpr complex<float> operator""if(long double d); constexpr complex<float> operator""if(unsigned long long d);
Returns: complex<float>{0.0f, static_­cast<float>(d)}.