28 Numerics library [numerics]

28.4 Complex numbers [complex.numbers]

28.4.1 General [complex.numbers.general]

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 that is not a cv-unqualified floating-point type ([basic.fundamental]) is unspecified.
Specializations of complex for cv-unqualified floating-point types are trivially copyable literal types ([basic.types.general]).
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) is well-formed,
  • reinterpret_cast<cv T(&)[2]>(z)[0] designates the real part of z, and
  • reinterpret_cast<cv T(&)[2]>(z)[1] designates 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] designates the real part of a[i], and
  • reinterpret_cast<cv T*>(a)[2*i + 1] designates the imaginary part of a[i].

28.4.2 Header <complex> synopsis [complex.syn]

namespace std { // [complex], class template complex template<class T> class complex; // [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, 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> constexpr T abs(const complex<T>&); template<class T> constexpr 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> constexpr complex<T> proj(const complex<T>&); template<class T> constexpr complex<T> polar(const T&, const T& = T()); // [complex.transcendentals], transcendentals template<class T> constexpr complex<T> acos(const complex<T>&); template<class T> constexpr complex<T> asin(const complex<T>&); template<class T> constexpr complex<T> atan(const complex<T>&); template<class T> constexpr complex<T> acosh(const complex<T>&); template<class T> constexpr complex<T> asinh(const complex<T>&); template<class T> constexpr complex<T> atanh(const complex<T>&); template<class T> constexpr complex<T> cos (const complex<T>&); template<class T> constexpr complex<T> cosh (const complex<T>&); template<class T> constexpr complex<T> exp (const complex<T>&); template<class T> constexpr complex<T> log (const complex<T>&); template<class T> constexpr complex<T> log10(const complex<T>&); template<class T> constexpr complex<T> pow (const complex<T>&, const T&); template<class T> constexpr complex<T> pow (const complex<T>&, const complex<T>&); template<class T> constexpr complex<T> pow (const T&, const complex<T>&); template<class T> constexpr complex<T> sin (const complex<T>&); template<class T> constexpr complex<T> sinh (const complex<T>&); template<class T> constexpr complex<T> sqrt (const complex<T>&); template<class T> constexpr complex<T> tan (const complex<T>&); template<class T> constexpr complex<T> tanh (const complex<T>&); // [complex.tuple], tuple interface template<class T> struct tuple_size; template<size_t I, class T> struct tuple_element; template<class T> struct tuple_size<complex<T>>; template<size_t I, class T> struct tuple_element<I, complex<T>>; template<size_t I, class T> constexpr T& get(complex<T>&) noexcept; template<size_t I, class T> constexpr T&& get(complex<T>&&) noexcept; template<size_t I, class T> constexpr const T& get(const complex<T>&) noexcept; template<size_t I, class T> constexpr const T&& get(const complex<T>&&) noexcept; // [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); } } }

28.4.3 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&) = default; template<class X> constexpr explicit(see below) 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.

28.4.4 Member functions [complex.members]

constexpr complex(const T& re = T(), const T& im = T());
Postconditions: real() == re && imag() == im is true.
template<class X> constexpr explicit(see below) complex(const complex<X>& other);
Effects: Initializes the real part with other.real() and the imaginary part with other.imag().
Remarks: The expression inside explicit evaluates to false if and only if the floating-point conversion rank of T is greater than or equal to the floating-point conversion rank of X.
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.

28.4.5 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: Assigns the value rhs.real() to the real part and the value rhs.imag() to the imaginary part of the complex value *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.

28.4.6 Non-member operations [complex.ops]

template<class T> constexpr complex<T> operator+(const complex<T>& lhs);
Returns: complex<T>(lhs).
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()).
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);
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, class charT, class traits> basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& is, complex<T>& x);
Preconditions: The input values are 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_base​::​​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 1: 
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]

28.4.7 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> constexpr T abs(const complex<T>& x);
Returns: The magnitude of x.
template<class T> constexpr 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> constexpr 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/IEC 9899:2018, 7.3.9.5
template<class T> constexpr complex<T> polar(const T& rho, const T& theta = T());
Preconditions: rho is non-negative and non-NaN.
theta is finite.
Returns: The complex value corresponding to a complex number whose magnitude is rho and whose phase angle is theta.

28.4.8 Transcendentals [complex.transcendentals]

template<class T> constexpr 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/IEC 9899:2018, 7.3.5.1
template<class T> constexpr 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/IEC 9899:2018, 7.3.5.2
template<class T> constexpr 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/IEC 9899:2018, 7.3.5.3
template<class T> constexpr 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/IEC 9899:2018, 7.3.6.1
template<class T> constexpr 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/IEC 9899:2018, 7.3.6.2
template<class T> constexpr 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/IEC 9899:2018, 7.3.6.3
template<class T> constexpr complex<T> cos(const complex<T>& x);
Returns: The complex cosine of x.
template<class T> constexpr complex<T> cosh(const complex<T>& x);
Returns: The complex hyperbolic cosine of x.
template<class T> constexpr complex<T> exp(const complex<T>& x);
Returns: The complex base-e exponential of x.
template<class T> constexpr 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 1: 
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> constexpr 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> constexpr complex<T> pow(const complex<T>& x, const complex<T>& y); template<class T> constexpr complex<T> pow(const complex<T>& x, const T& y); template<class T> constexpr complex<T> pow(const T& x, const complex<T>& y);
Returns: The complex power of base x raised to the 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> constexpr complex<T> sin(const complex<T>& x);
Returns: The complex sine of x.
template<class T> constexpr complex<T> sinh(const complex<T>& x);
Returns: The complex hyperbolic sine of x.
template<class T> constexpr complex<T> sqrt(const complex<T>& x);
Returns: The complex square root of x, in the range of the right half-plane.
[Note 2: 
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> constexpr complex<T> tan(const complex<T>& x);
Returns: The complex tangent of x.
template<class T> constexpr complex<T> tanh(const complex<T>& x);
Returns: The complex hyperbolic tangent of x.

28.4.9 Tuple interface [complex.tuple]

template<class T> struct tuple_size<complex<T>> : integral_constant<size_t, 2> {}; template<size_t I, class T> struct tuple_element<I, complex<T>> { using type = T; };
Mandates: I < 2 is true.
template<size_t I, class T> constexpr T& get(complex<T>& z) noexcept; template<size_t I, class T> constexpr T&& get(complex<T>&& z) noexcept; template<size_t I, class T> constexpr const T& get(const complex<T>& z) noexcept; template<size_t I, class T> constexpr const T&& get(const complex<T>&& z) noexcept;
Mandates: I < 2 is true.
Returns: A reference to the real part of z if I == 0 is true, otherwise a reference to the imaginary part of z.

28.4.10 Additional overloads [cmplx.over]

The following function templates have additional constexpr overloads: arg norm conj proj imag real
The additional constexpr overloads are sufficient to ensure:
  • If the argument has a floating-point type T, then it is effectively cast to complex<T>.
  • Otherwise, if the argument has integer type, then it is effectively cast to complex<double>.
Function template pow has additional constexpr overloads sufficient to ensure, for a call with one argument of type complex<T1> and the other argument of type T2 or complex<T2>, both arguments are effectively cast to complex<common_type_t<T1, T2>>.
If common_type_t<T1, T2> is not well-formed, then the program is ill-formed.

28.4.11 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)}.