Every number so far has been a whole one. The moment you write a game, you need the in-between: a ship that drifts half a pixel a frame, a ball at two-thirds speed.
The machine counts in whole steps. So how do you give it a fraction?
We will compare two ways to store fractions. This unit looks at binary floating-point; the next looks at fixed-point. Each has limits, and the right choice depends on the job.
Let the point float
The first answer stores a limited set of significant bits together with a scale. That scale lets the binary point float: the same storage can describe tiny fractions or large values, within its range.
Many languages use floating-point for fractional arithmetic. Our explanatory notation can show a fraction like this:
SHOW 1 / 30.33333333
This display stops after eight decimal places. That alone does not tell us how the value is stored: a display can print fewer digits than the machine holds.
A third needs a recurring expansion in both binary and decimal. A finite binary floating-point format therefore stores an approximation to it.
Floating-point has finite precision. Some values fit exactly; others must be rounded.
Which fractions fit?
The reason goes back to Counting in Twos.
The places to the left of the point double as you go: 1, 2, 4, 8. The places to the right halve: a half, a quarter, an eighth, a sixteenth. Every fraction the machine holds exactly is built by adding some of those together.
A half is one of them. So is three quarters, which is a half and a quarter. These values fit exactly when the format has enough precision and range.
Now try a tenth. There is no run of halves and quarters and eighths that comes to exactly 0.1. It recurs, on and on, the way a third does in tens:
0.1 in tens 0.1 exact
0.1 in twos 0.000110011001100… recurringSo the written decimal 0.1 is exact, but a finite binary floating-point
representation of it is rounded. This is a property of the format, not every way
a computer can represent a number.
Rounding can affect later calculations, but not every operation adds an error.
For example, a half plus a quarter is three quarters: all three values fit exactly
in the Spectrum’s numeric format. Adding a tiny value to a large one can instead lose the small change: in Spectrum
BASIC, (10000000000+1)-10000000000 gives 0 rather than 1.
Exact equality is useful when an exact match is what you mean and the values are known to be exact. For approximate calculated values, decide how close is close enough for the task. There is no single tolerance that suits every game rule.
Can binary floating-point store 0.5 exactly? What about 0.1?
Yes for 0.5: one binary place holds a half, provided the format’s range includes it. No for 0.1: its binary expansion repeats, so a finite format must round it. A short printed answer does not reveal all the stored bits.
What the machine has to do
The Spectrum’s Z80 has no floating-point arithmetic instructions. Its BASIC ROM works out these operations in software using simpler instructions. That can cost more work than an integer addition.
The cost depends on the machine, representation and calculation. Whether it fits a game loop depends on how much work that loop does. Choose a representation that meets the game’s precision, range and timing needs; measure before declaring it too slow.
When it’s wrong, see why
- A float was not exactly the value you expected. Check whether the format can represent it
exactly. A tidy decimal like
0.1needs rounding in binary floating-point. - Two floats that should be equal were not. Different calculations may have rounded differently. Choose a comparison that matches the task and its allowed error.
- Small errors grew. Rounding errors can accumulate or cancel. Check the operations and the size of the values; do not assume each step adds the same error.
What you’ve learnt
- A floating-point number lets the point sit wherever the value needs it.
- It stores significant bits and a scale, with limits on precision and range.
- Some fractions, such as 0.5, fit exactly. Others, such as 0.1, need rounding in a finite binary format.
- Software floating-point has a cost; whether it is suitable depends on the target and task.
What’s next
In Unit 5 we agree on a fixed scale instead. That makes some operations simpler, but gives us another precision and range trade-off to manage.
Sources
Sinclair Research, ZX Spectrum BASIC Programming, chapter 24, pp. 169–170, explains the binary representation and rounding of one tenth. The Amstrad ZX Spectrum +3 User Manual, p. 78, shows the loss of a small addition to a large value. These are Spectrum examples, not a claim about every format.