# complex.h **`complex.h`** is what you include when you need the maths to work directly with complex numbers, rather than manually tracking real and imaginary parts in separate `double` variables. Added in C99, it gives you `_Complex` types, the imaginary unit `I`, and the full set of functions for magnitude, phase, conjugate, exponential, trig, and so on. ```c #include double complex z = 3.0 + 4.0 * I; // I is sqrt(-1) double mag = cabs(z); // magnitude: sqrt(3² + 4²) = 5.0 double phase = carg(z); // phase angle: atan2(4, 3) ≈ 0.9273 rad double complex c = conj(z); // conjugate: 3 - 4i ``` The arithmetic operators work natively on `double complex` — addition, subtraction, multiplication, and division all just work. The full function set mirrors ``: `csin`, `ccos`, `cexp`, `clog`, `cpow`, `csqrt`, `creal`, `cimag`. Float variants have an `f` suffix (`cabsf`) and long double variants have an `l` suffix. Complex numbers come up in signal processing (FFT, filter design), electrical engineering (impedance), and quantum mechanics (wave functions). For heavy numerical work, libraries like FFTW provide the optimised implementations; `` is the language-level foundation they sit on top of. ## Practice ```c // compile: gcc -o cplex cplex.c -lm // run: ./cplex // description: basic complex arithmetic; Euler's formula as a sanity check #include #include #include int main(void) { double complex z = 3.0 + 4.0 * I; printf("|z| = %.1f\n", cabs(z)); // 5.0 printf("arg(z) = %.4f rad\n", carg(z)); // 0.9273 printf("conj(z) = %.1f%+.1fi\n", creal(conj(z)), cimag(conj(z))); // Euler's formula: e^(i*pi) should equal -1 + 0i double complex euler = cexp(I * M_PI); printf("e^(i*pi) = %.6f%+.6fi\n", creal(euler), cimag(euler)); return 0; } ``` The last line demonstrates Euler's formula: $e^{i\pi} \approx -1$. The imaginary part will be a very small number near zero but not exactly zero — floating-point rounding applies to complex arithmetic just as it does to real arithmetic. If you are seeing values like `-1.000000+0.000000i`, that tiny residue is hidden by the format width; try `%.20f` to see it.