Floating-point numbers

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;
}
Open in compiler

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;
}
Open in compiler

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.

TypeBytesSignificant digitsLargest value
float4about 7about 3.4 × 10³⁸
double8about 15 to 16about 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

1. Why is 0.1 + 0.2 == 0.3 false for doubles?
2. How should two doubles be compared?
3. About how many significant digits does a float keep?
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.