Lesson
The theory — Floating point278 words
A floating-point number is a whole number multiplied by a power of two: (−1)s × 1.f × 2E−1023. The format decides how many bits go to E and how many to f, and that single split fixes both how far the format reaches and how finely it can tell two numbers apart.
What each symbol means
s- the sign bit, 0 for positive and 1 for negative. It sits on its own rather than being folded into the number, which is why the format has both a +0 and a −0.
E- the exponent field, held with 1023 added to it so it can run negative without needing a sign of its own. It chooses which range you are in, and the range is what decides how far apart the neighbours are.
f- the fraction: 52 bits following a leading 1 that is never stored, because a normalised number always starts with one. Those 52 bits are the entire precision, and the exponent adds none of its own.
- Assumes
- That the number is finite and normal. Below 2−1022 the leading 1 is dropped and the format keeps going by giving up precision instead, so the smallest positive double is 4.94 × 10−324 and carries a single bit of significand.
- Breaks when
- In two places, both of them in real code. Comparing two computed values with
=fails whenever they were reached by different routes, because different routes round differently. And a long sum depends on the order it is added in: run a list forwards and backwards and the totals differ. Adding the smallest terms first loses the least.
Problem solved in full
-
A payments system holds amounts in pounds as binary64. Show that £0.10 and £0.20 are both stored slightly high, that adding them does not give £0.30, and say what a payments engineer does about it.
-
0.1 in base two is 0.0001 followed by 1001 repeating for ever. A tenth needs a five in its denominator and a binary fraction has nothing but twos, so the expansion never closes.
-
53 binary digits are kept and the rest are rounded away. Here they round upwards, so the stored value sits above 0.1 by 5.55 × 10⁻¹⁸, and the rounding step on the page shows that direction as an arrow.
-
0.2 is those same 53 digits with the exponent one higher, so its error is exactly double: 1.11 × 10⁻¹⁷. Put 0.2 in the box and compare the two error cards.
-
Added together, the two stored values land exactly on the midpoint between the two doubles either side of 0.3. A tie goes to whichever neighbour ends in an even bit, and that is the one above.
-
So what comes back is 0.3000000000000000444089209850062616169452667236328125, and every later calculation carries it.
-
Now type 10 and 20 instead of 0.1 and 0.2. Both are whole numbers well below 2⁵³, both are held exactly, and 10 + 20 is 30 with nothing lost anywhere.
Answer
Hold money as a whole number of the smallest unit, pence rather than pounds, and the arithmetic is exact because every integer up to 2⁵³ is exact. The only rounding left is the one you write yourself, at the moment you choose, where you can point at it. The tool shows both halves in ten seconds: type 0.1 and the error card is not zero, type 10 and it is.
-