Complex types consist of two parts: a real part and an imaginary part. Imaginary types consist of only the imaginary part.
There are three type specifiers for complex types:
To declare a data object that is a complex type, use the one of the following type specifiers:
>>-+-float-------+--complex------------------------------------>< +-double------+ '-long double-'
The imaginary unit I is a constant of type float complex. The predefined macro _Complex_I represents a constant expression of type const float _Complex, with the value of the imaginary unit.
The complex type and the real floating type are collectively called the floating types. Each floating type has a corresponding real type. For a real floating type, it is the same type. For a complex type, it is the type given by deleting the keyword _Complex from the type name.
The representation and alignment requirements of a complex type are the same as an array type containing two elements of the corresponding real type. The real part is equal to the first element; the imaginary part is equal to the second element.
Arithmetic conversions are the same as those for the real type of the complex type. If either operand is a complex type, the result is a complex type, and the operand having the smaller type for its real part is promoted to the complex type corresponding to the larger of the real types. For example, a double _Complex added to a float _Complex will yield a result of type double _Complex.
When casting a complex type to a real type, the imaginary part is dropped. When the value of a real type is converted to a complex type, the real part of the complex result value is determined by the rules of conversion to the corresponding real type, and the imaginary part of the complex result value is a positive zero or an unsigned zero.
The equality and inequality operators have the same behavior as for real types. None of the relational operators may have a complex type as an operand.
Related References