1+ #include <errno.h>
2+ #include <fenv.h>
3+ #include <math.h>
4+ #include <stdio.h>
5+
6+ // Compilation instructions!
7+ // for compiling math you need add -lm at the very end!
8+ // 1. The C Standard vs. Implementations
9+
10+ // The C standard (ISO/IEC 9899) says that functions like sqrt, sin, log,
11+ // feclearexcept, etc. exist in the library.
12+
13+ // But the standard doesn’t say how they must be organized in the actual runtime
14+ // system.
15+
16+ // Compiler vendors (like GCC on Unix) are free to put them in a separate
17+ // library (libm) instead of the default libc.
18+
19+ // 2. Why Split into libc and libm?
20+
21+ // Historical reason (Unix in the 1970s):
22+
23+ // Early C programs often didn’t need floating-point math (think of simple
24+ // utilities and text processing).
25+
26+ // Floating-point math routines were large and sometimes required special
27+ // hardware support (math co-processors).
28+
29+ // To avoid bloating every program, they were separated into libm.
30+
31+ // That way, only programs that actually needed math functions had to pay the
32+ // cost of linking libm.
33+
34+ // 3. GCC Linking Rules
35+
36+ // By default, gcc file.c -o prog links libc, because every C program needs
37+ // basic functions (printf, malloc, etc.).
38+
39+ // But it does not link libm unless you explicitly request it with -lm.
40+
41+ // Linker order matters:
42+
43+ // gcc file.c -lm -o prog # works
44+ // gcc -lm file.c -o prog # usually fails
45+
46+ // because the linker only searches libraries after seeing unresolved
47+ // references.
48+
49+ // #pragma STDC FENV_ACCESS ON
50+
51+ int main (void ) {
52+ printf ("sqrt(100) = %f\n" , sqrt (100 ));
53+
54+ printf ("sqrt(-1.0) = %f\n" , sqrt (-1.0 ));
55+
56+ errno = 0 ;
57+ feclearexcept (FE_ALL_EXCEPT );
58+
59+ printf ("sqrt(-1.0) = %f\n" , sqrt (-1.0 ));
60+
61+ if (errno == EDOM ) perror ("errno == EDOM" );
62+
63+ if (fetestexcept (FE_INVALID )) puts ("FE_INVALID raised" );
64+
65+ return 0 ;
66+ }
0 commit comments