The <float.h> header defines macros that describe the limits and precision of float, double, and long double on your platform. Instead of guessing how big a float can get or how many decimal digits are reliable, you read constants like FLT_MAX and DBL_EPSILON at compile time.
01
FLT_MAX
Largest float.
02
FLT_MIN
Smallest normal.
03
EPSILON
Gap at 1.0.
04
FLT_DIG
Decimal digits.
05
DBL_*
Double limits.
06
Portable
Use macros.
Fundamentals
Definition and Usage
Floating-point numbers cannot represent every real value exactly. They have a finite range (minimum and maximum magnitude) and finite precision (how many significant digits you can trust). <float.h> exposes those properties as preprocessor macros so your code adapts to the compiler and CPU.
Macros are grouped by type prefix: FLT_ for float, DBL_ for double, and LDBL_ for long double. The most commonly used are *_MAX, *_MIN, *_EPSILON, and *_DIG.
💡
Beginner Tip
FLT_EPSILON is not “overall precision.” It is machine epsilon—the smallest value you can add to 1.0f and still get a different result. The old reference mislabeled it as “precision value.”
Foundation
📝 Syntax
Include the header:
C
#include <float.h>
Essential float macros
FLT_MAX — largest finite positive float.
FLT_MIN — smallest positive normalizedfloat.
FLT_EPSILON — smallest float where 1.0f + FLT_EPSILON != 1.0f.
FLT_DIG — decimal digits of precision you can round-trip through text.
FLT_MANT_DIG — bits in the significand (mantissa).
FLT_MIN_EXP / FLT_MAX_EXP — exponent range.
Essential double macros
DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_DIG
DBL_MANT_DIG, DBL_MIN_EXP, DBL_MAX_EXP
Essential long double macros
LDBL_MAX, LDBL_MIN, LDBL_EPSILON, LDBL_DIG
LDBL_MANT_DIG, LDBL_MIN_EXP, LDBL_MAX_EXP
Other useful macros
FLT_RADIX — radix of the exponent representation (usually 2).
DECIMAL_DIG — decimal digits needed to round-trip any floating type to text and back.
FLT_TRUE_MIN (C11) — smallest positive float, including subnormals.
Headers and linking
#include <float.h> — macros only, no link flag needed.
Pair with <math.h> for fabs, sqrt, etc. (-lm on GCC).
Compile: gcc program.c -std=c11 -o program
Cheat Sheet
⚡ Quick Reference
Macro
Type
Typical meaning (IEEE 754)
FLT_MAX
float
~3.4 × 1038
FLT_EPSILON
float
~1.2 × 10−7
FLT_DIG
float
6 decimal digits
DBL_MAX
double
~1.8 × 10308
DBL_EPSILON
double
~2.2 × 10−16
DBL_DIG
double
15 decimal digits
Exact values vary by platform. Always use the macros—never hard-code these numbers.
Range
if (x > FLT_MAX)
Overflow guard
Epsilon
DBL_EPSILON
Near-equal test
Digits
printf("%.*g", FLT_DIG, x)
Safe print width
Radix
FLT_RADIX /* usually 2 */
Base of exponent
Hands-On
Examples Gallery
Compile with gcc file.c -std=c11 -o out. Add -lm when using fabs from <math.h>. Output values depend on your platform; samples below match typical GCC on x86-64.
📚 Getting Started
Discover what your compiler reports for each floating type.
Example 1 — Print Floating-Point Limits
Expanded from the reference with correct labels and complete output for all three types.
Each macro is a compile-time constant. The old reference output showed only long-double lines and called epsilon “precision value”—here all three sections appear with accurate names.
Example 2 — See Machine Epsilon in Action
Verify the definition: 1.0 + epsilon changes the stored value.
C
#include <float.h>
#include <stdio.h>
int main(void) {
float a = 1.0f;
float b = 1.0f + FLT_EPSILON;
float c = 1.0f + FLT_EPSILON / 2.0f;
printf("1.0f + FLT_EPSILON = %.9f (different: %s)\n",
b, (a != b) ? "yes" : "no");
printf("1.0f + FLT_EPSILON/2 = %.9f (different: %s)\n",
c, (a != c) ? "yes" : "no");
return 0;
}
Adding full FLT_EPSILON bumps the float past what 1.0f can distinguish; half epsilon rounds back to 1.0f. This is why == fails for floating-point math.
📈 Practical Patterns
Compare safely, guard range, and pick the right type.
Example 3 — Approximate Equality with DBL_EPSILON
Never use a == b for floats; compare the difference to epsilon.
C
#include <float.h>
#include <math.h>
#include <stdio.h>
int approx_equal(double a, double b) {
return fabs(a - b) <= DBL_EPSILON * 10.0;
}
int main(void) {
double x = 0.1 + 0.2;
double y = 0.3;
printf("x = %.17f\n", x);
printf("y = %.17f\n", y);
printf("x == y: %s\n", (x == y) ? "true" : "false");
printf("approx_equal: %s\n", approx_equal(x, y) ? "true" : "false");
return 0;
}
📤 Output:
x = 0.30000000000000004
y = 0.30000000000000004
x == y: false
approx_equal: true
How It Works
0.1 + 0.2 is not exactly 0.3 in binary floating-point. DBL_EPSILON gives a scale for “close enough.” Production code often uses relative tolerance; this simple pattern teaches the idea.
Example 4 — Range Check Before Multiply
Use FLT_MAX to detect likely overflow before it becomes infinity.
C
#include <float.h>
#include <stdio.h>
int safe_multiply(float a, float b, float *out) {
if (a != 0.0f && b > FLT_MAX / a) {
return -1; /* would overflow */
}
*out = a * b;
return 0;
}
int main(void) {
float result;
float big = FLT_MAX / 2.0f;
if (safe_multiply(big, 3.0f, &result) != 0) {
printf("Overflow avoided: product too large for float\n");
} else {
printf("Result: %e\n", result);
}
return 0;
}
📤 Output:
Overflow avoided: product too large for float
How It Works
Before multiplying, check whether |a * b| would exceed FLT_MAX. Real libraries also handle NaN, infinity, and negative values; this shows the core idea of using float.h limits defensively.
Example 5 — Choose float vs double by FLT_DIG
Print how many decimal digits each type can represent reliably.
Radix (usually 2): 2
float decimal digits: 6 (FLT_DIG)
double decimal digits: 15 (DBL_DIG)
DECIMAL_DIG (widest): 21
Use float for ~6 significant digits; double for ~15.
How It Works
FLT_DIG tells you how many decimal digits round-trip safely through a float. Financial or scientific code that needs more digits should use double or long double.
Applications
🚀 Common Use Cases
Overflow prevention — guard multiplies and exponentials with FLT_MAX / DBL_MAX.
Fuzzy comparisons — use *_EPSILON instead of == for floats.
Formatted output — limit printf precision with FLT_DIG or DECIMAL_DIG.
Memory vs precision — pick float arrays when FLT_DIG is enough.
Unit tests — assert results within epsilon of expected values.
Cross-platform libraries — never hard-code IEEE 754 constants; read macros.
🧠 How float.h Works
1
Include float.h
Compiler exposes limits for its floating-point implementation.
Setup
2
Read macros
FLT_MAX, DBL_EPSILON, etc. expand to constants at compile time.
Constants
3
Apply in logic
Range checks, tolerance comparisons, and format width decisions.
Use
=
💬
Portable float code
Same source adapts when long double is wider on another machine.
Important
📝 Notes
Macro values are implementation-defined—print them once on your target platform if unsure.
FLT_MIN is the smallest normalized positive value; subnormals can be smaller.
*_EPSILON is defined around 1.0; tolerance for large numbers may need scaling.
long double size varies: 80-bit, 128-bit, or same as double on some compilers.
Floating literals like 3.14 are double unless suffixed with f or L.
For integer limits, see <limits.h>; for math functions, see <math.h>.
Performance
⚡ Optimization
float uses half the memory of double and can be faster on SIMD or embedded hardware. Use FLT_DIG to confirm six digits is enough before switching. Macros themselves have zero runtime cost—they are resolved at compile time.
Wrap Up
Conclusion
<float.h> is your portable guide to floating-point range and precision. Use *_MAX and *_MIN for bounds, *_EPSILON for near-equality, and *_DIG to pick the right type and print format.
Pair it with <math.h> for transcendental functions and <errno.h> when math calls set EDOM or ERANGE.
Print limits once during development to learn your platform
Use %.Ng with N <= FLT_DIG for safe float output
❌ Don’t
Call FLT_EPSILON “overall precision”
Assume long double is always wider than double
Hard-code IEEE 754 constants from a textbook
Compare floats after different sequences of operations without tolerance
Mix float and double unintentionally in expressions
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about float.h
Floating-point limits in C, explained simply.
5
Core concepts
💬01
FLT_MAX
Upper bound.
Range
📚02
EPSILON
Gap at 1.0.
Compare
📈03
FLT_DIG
Safe digits.
Precision
📄04
DBL_*
Double set.
Default
🌐05
Portable
Use macros.
Platform
❓ Frequently Asked Questions
float.h defines implementation-specific macros for floating-point types: minimum and maximum values, machine epsilon, decimal digits of precision, and exponent ranges. Use it to write portable code that respects float, double, and long double limits on any platform.
FLT_EPSILON is the smallest positive float such that 1.0f + FLT_EPSILON != 1.0f. It is called machine epsilon—the gap at 1.0, not overall precision. Use DBL_EPSILON for double comparisons when you need tighter tolerance.
FLT_MIN is the minimum positive normalized float. Subnormal (denormalized) values can be smaller. C11 adds FLT_TRUE_MIN for the smallest positive value including subnormals. For most beginners, FLT_MIN is the practical lower bound for normal math.
No. Exact values depend on the compiler and hardware (IEEE 754 is common but not guaranteed). Always use the macros at runtime instead of hard-coding numbers like 3.402823e+38.
Default to double for general calculations—it has more precision (DBL_DIG decimal digits) and is the default type for floating literals unless you add f. Use float when memory bandwidth matters (large arrays, GPUs) and the reduced precision is acceptable.
float.h covers floating-point types (float, double, long double). limits.h covers integer types (int, long, char). Both provide portable limit macros; use the header that matches the type you are working with.
Did you know?
The famous bug 0.1 + 0.2 == 0.3 is false in C because decimals like 0.1 have no exact binary fraction. FLT_EPSILON and DBL_EPSILON from float.h quantify the gap—which is why financial systems sometimes use integer cents or decimal libraries instead of raw double.