Table of Contents
<complex.h>
In C programming language, <complex.h> is a header which is part of the C standard library (specifically, C99). It implements the algebra of complex numbers $\mathbb C$.
You need at least version C99 to use this header, so compile with gcc -std=c99 main.c -o program.
Usage
Here's an example that creates a complex number $2 + i3$
// Compile: gcc -std=c99 main.c -o program // Run: ./program // Output: Complex number 'z' equals to '2 + i3' #include <complex.h> int main() { const double complex z = 2 + I * 3; printf("Complex number 'z' equals to '%g + i%g'", creal(z), cimag(z)); return 0; }
This syntax surprised me the first time I saw it. How exactly does including a header like <complex.h> give double the ability to become double complex? Can a header really add new syntax to C programming language?
Well, no. In fact, C99 has a keyword called _Complex already, which you can use even without including <complex.h>. This is why I using version C99 is important if you want to use this header! In traditional C programming language (a.k.a. C89), there is no _Complex keyword.
// Compile: gcc -std=c99 main.c -o program // Run: ./program // Output: none /* #include <complex.h> */ int main() { float _Complex z {2, 3}; // most commonly 32bit double _Complex z {2, 3}; // most commonly 64bit long double _Complex z {2, 3}; // most commonly 128bit return 0; }
What <complex.h> header actually does is:
One, it provides a macro #define I _Complex_I for the imaginary unit $i$. For example $z = 2 + i3$ is written as double complex z = 2 + I * 3. Macros I and _Complex_I are just a short hand for (double _Complex){0, 1}.
Two, it provides a myriad of functions prefixed by the character 'c' such as cabs(z), cexp(z), clog(z), csin(z), ccos(z), ctan(z), … These implement complex functions $|z|$, $e^z$, $\log(z)$, $\sin(z)$, $\cos(z)$, $\tan(z)$. You will need to link the standard math library with -lm to use these! The -lm option tells the linker to link libm.so library, which is located in /usr/lib
So, the following is likely how you want to compile your program with GCC, if you want to use complex numbers:
gcc -lm -std=c99 main.c -o main
Illustration
The following example illustrates most (though not all) of the header's capabilities.
You can extend the example by adding more C_PRINT(...) calls!
// Compile: gcc -std=c99 main.c -o main // Execute:./main /* z = 2 + i3 w = 1 + i4 z + w = 3 + i7 z - w = 1 - i1 z * w = -10 + i11 z / w = 0.823529 - i0.294118 creal(z) = 2 - i0 cimag(z) = 3 - i0 cabs(z) = 3.60555 - i0 carg(z) = 0.982794 - i0 */ #include <stdio.h> #include <complex.h> #include <math.h> #define C_PRINT(z) \ do { \ double real = creal((z)); \ double imag = cimag((z)); \ char *sign_1 = real > 0 ? " " : "-"; \ char *sign_2 = imag > 0 ? "+" : "-"; \ printf(("%10s = %s%g %s i%g\n"), (#z), sign_1, fabs(real), sign_2, fabs(imag)); \ } while (0) int main() { double complex z = 2.0 + I * 3.0; double complex w = 1.0 + I * 4.0; C_PRINT(z); C_PRINT(w); C_PRINT(z + w); C_PRINT(z - w); C_PRINT(z * w); C_PRINT(z / w); C_PRINT(creal(z)); C_PRINT(cimag(z)); C_PRINT(cabs(z)); C_PRINT(carg(z)); return 0; }
