float vs double in C: Precision, Memory, and When to Use Which

How C’s float and double differ in precision, size, range, literals and format specifiers, with real compiler output showing where float goes wrong.
C
Programming
Tutorial
Author

Abdullah Al Mahmud

Published

September 26, 2026

float and double both store decimal (floating-point) numbers in C, but they differ in precision, memory usage, and range.

A double spends more bits on the mantissa (precision) and the exponent (range) than a float

The fundamental difference is that double provides roughly twice the precision of float. Modern desktop computers handle both at similar speeds, so double is generally preferred unless memory is tightly restricted.

Quick Comparison

Feature float double
Precision Single (~6–7 decimal digits) Double (~15 decimal digits)
Memory size 4 bytes (32 bits) 8 bytes (64 bits)
IEEE 754 bit layout 1 sign, 8 exponent, 23 mantissa 1 sign, 11 exponent, 52 mantissa
Range ≈ 1.2 × 10⁻³⁸ to 3.4 × 10⁺³⁸ ≈ 2.2 × 10⁻³⁰⁸ to 1.8 × 10⁺³⁰⁸
printf specifier %f %f (%lf also accepted)
scanf specifier %f %lf
Literal 3.14f (needs f or F) 3.14 (the default)

The ranges above are the smallest and largest normal positive values. You can check every number on your own machine with sizeof and the constants in <float.h>.

1. Precision and the Rounding Trap

A float has 23 bits for its fractional part (the mantissa), so it starts losing accuracy after about 7 significant digits. A double has 52 bits and stays accurate to about 15.

#include <stdio.h>

int main() {
    // Both variables are assigned the same long decimal
    float pi_float = 3.141592653589793f;
    double pi_double = 3.141592653589793;

    // %.15f prints 15 digits after the decimal point
    printf("Float value:  %.15f\n", pi_float);
    printf("Double value: %.15f\n", pi_double);
    return 0;
}

Output (compiled with GCC):

Float value:  3.141592741012573
Double value: 3.141592653589793

The float is already wrong from the 7th decimal place onward (3.1415927... instead of 3.1415926...).

NoteWhy do float and double often look identical when printed?

%f prints only 6 digits after the decimal point by default, which hides the difference. Ask for more digits, such as %.15f, to see it.

2. Neither Can Store 0.1 Exactly

Computers store numbers in binary, and 0.1 has no finite binary representation. Both types store the nearest approximation; double is just much closer.

float  a = 0.1f;
double b = 0.1;
printf("%.20f\n", a);   // 0.10000000149011611938
printf("%.20f\n", b);   // 0.10000000000000000555

This is why comparing floating-point numbers with == is risky, even with double:

printf("%d\n", 0.1 + 0.2 == 0.3);   // 0 (false!)
printf("%.17f\n", 0.1 + 0.2);       // 0.30000000000000004

Instead of ==, check whether the difference is tiny: fabs(x - y) < 1e-9 (needs <math.h>).

3. Errors Accumulate

Small rounding errors add up when repeated. Here we add 0.1 ten million times, so the exact answer is 1,000,000:

float  s = 0;
double d = 0;
for (int i = 0; i < 10000000; i++) {
    s += 0.1f;
    d += 0.1;
}
printf("float:  %f\n", s);   // 1087937.000000  (about 9% off!)
printf("double: %f\n", d);   // 999999.999839   (off by about 0.0002)

A float also runs out of whole-number precision early: above 16,777,216 (2²⁴) it cannot represent every integer, so 16777216.0f + 1.0f is still 16777216.0.

4. Literals and Defaults

In C, any decimal number written directly in code (such as 3.14) is a double. To make a float, add an f or F suffix:

float  x = 3.14f;   // float literal
float  y = 3.14;    // double literal silently converted to float
double z = 3.14;    // double literal

Writing float y = 3.14; compiles fine, but the compiler converts a double to a float, which can lose precision. Use the f suffix to be explicit.

5. Mixing Types

When a float and a double meet in an expression, the float is promoted to double. Also, printf always receives a double for %f, which is why %f works for both types:

float f = 1 / 3.0f;
printf("%f\n", f);          // 0.333333
printf("%.15f\n", (double) f);  // 0.333333343267441 (the float's rounding error is still there)

Promoting to double does not repair an error that already happened; it only prevents new ones.

When to Use Which?

Use double for:

  • Everyday programming and general calculations.
  • Scientific computing, statistics, and simulations, where errors can grow.
  • Large sums or long loops, where rounding errors accumulate.

Use float for:

  • Memory-critical systems, such as embedded hardware with limited RAM.
  • Huge arrays of floating-point numbers, where halving the memory matters.
  • Graphics, games, and GPU computing (CUDA), where throughput matters more than extreme accuracy.
TipRule of thumb

Start with double. Switch to float only when you have a measured memory or speed reason, and you know the reduced precision is acceptable.

References

  1. Float vs double: what’s the key difference? (Reddit r/learnprogramming)
  2. Difference between float and double in C/C++ (GeeksforGeeks)
  3. C float and double (GeeksforGeeks)
  4. C++ float and double (Programiz)
  5. When do you use float and when do you use double? (Software Engineering Stack Exchange)
  6. Difference between float and double in C/C++ (Scaler)
  7. Double vs float in C++ (freeCodeCamp)
  8. Difference between float and double (Unstop)
  9. Float vs double (MeshLib)