A double stores a number like scientific notation in binary: a sign, about 53 bits of significant digits (the mantissa) and a power of two (the exponent). This is the IEEE 754 standard, used by almost every computer.
0.1 is not exact
#include <stdio.h>
#include <math.h>
int main(void) {
double a = 0.1 + 0.2;
printf("0.1 + 0.2 = %.17g\n", a);
printf("equal to 0.3? %d\n", a == 0.3);
printf("close to 0.3? %d\n", fabs(a - 0.3) < 1e-9);
return 0;
}In base 10, 1/3 = 0.333... never ends. In base 2, 0.1 never ends either, so a double holds the nearest binary fraction, which is a tiny bit off. 0.1 + 0.2 gives 0.30000000000000004, not 0.3, so == says they differ. Printing with %.17g shows all the digits.
Compare floating-point numbers with a small tolerance instead: fabs(a - b) < 1e-9.
Precision runs out
#include <stdio.h>
int main(void) {
double big = 1e16;
printf("1e16 + 1 = %.1f\n", big + 1);
double sum = 0;
for (int i = 0; i < 10; i++) sum += 0.1;
printf("0.1 added ten times = %.17g\n", sum);
float f = 16777216.0f;
printf("float 16777216 + 1 = %.1f\n", f + 1.0f);
return 0;
}A double keeps about 15 to 16 significant decimal digits, a float only about 7. Adding 1 to 10¹⁶ changes nothing, because the 1 falls beyond the digits it keeps. And adding 0.1 ten times does not give exactly 1.0.
| Type | Bytes | Significant digits | Largest value |
|---|---|---|---|
float | 4 | about 7 | about 3.4 × 10³⁸ |
double | 8 | about 15 to 16 | about 1.8 × 10³⁰⁸ |
Money. Never store money as double: 0.1 taka cannot be exact. Store whole paisa in an integer (long long paisa = 1050; for 10.50 taka).
Quick check
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.