# float.h **`float.h`** tells you the hard limits of floating-point arithmetic on the platform you are compiling for: how many decimal digits `double` can represent reliably, the largest and smallest values, and machine epsilon. You reach for it when writing numerical code that needs to be correct across platforms rather than just on your development machine. The most useful macros for `double`: | Macro | Typical value | Meaning | | `DBL_EPSILON` | ~2.22e-16 | Smallest value where `1.0 + epsilon != 1.0` | | `DBL_MAX` | ~1.80e+308 | Largest finite double | | `DBL_MIN` | ~2.22e-308 | Smallest normalised positive double | | `DBL_DIG` | 15 | Decimal digits of precision | | `DBL_MANT_DIG` | 53 | Binary mantissa digits | Equivalent macros exist for `float` (`FLT_*`) and `long double` (`LDBL_*`). `FLT_RADIX` is the exponent base — 2 on every modern platform. `DBL_EPSILON` is the constant you need for floating-point comparisons. Instead of `a == b`, use a relative comparison: ```c #include #include int nearly_equal(double a, double b) { return fabs(a - b) <= DBL_EPSILON * fmax(fabs(a), fabs(b)); } ``` The right threshold depends on how many operations accumulated error, but `DBL_EPSILON` is the floor: no two distinct doubles within this range can be reliably distinguished. ## Practice ```c // compile: gcc -o floatlimits floatlimits.c -lm // run: ./floatlimits // description: print floating-point limits and demonstrate machine epsilon behaviour #include #include #include int main(void) { printf("DBL_EPSILON = %.2e\n", DBL_EPSILON); printf("1.0 + DBL_EPSILON != 1.0: %s\n", (1.0 + DBL_EPSILON != 1.0) ? "true" : "false"); printf("1.0 + DBL_EPSILON/2 != 1.0: %s\n", (1.0 + DBL_EPSILON/2.0 != 1.0) ? "true" : "false"); printf("DBL_MAX = %.6e\n", DBL_MAX); printf("DBL_MAX*2 = %g\n", DBL_MAX * 2.0); // infinity printf("DBL_DIG = %d decimal digits\n", DBL_DIG); return 0; } ``` The `DBL_EPSILON/2` line is the key insight: add half an epsilon to 1.0 and it disappears, because it falls below the resolution of the mantissa at that scale. `DBL_MAX * 2.0` prints `inf`, showing where the exponent range ends. Run this on a 32-bit and a 64-bit machine and the `double` values will be identical (IEEE 754 is the same), but `LDBL_EPSILON` may differ because `long double` is 80-bit on x86 and 64-bit on some other architectures.