Fixed point arithmetic is a compromise used in the Doom engine to have fractional values while still using integer instructions. At the time of Doom's development, there was a significant speed advantage to avoiding floating point instructions, which were quite slow especially on low-end CPUs that had neither an integrated FPU nor a coprocessor.
In a fixed point system, a 32-bit integer is split into two parts: the upper 16 bits are the integral part, and the lower 16 bits are the fractional part. For example, the value 2.5 is stored as 163,840 (0x28000).
Since fixed point units are technically integers instead of a native unit type, operations involving a fixed point value and another must obey certain rules.
With an integerEdit
Additions and subtractions require conversion. For example, 2.5 + 2 will not yield 4.5 but 2.500030517578125. Either the integer value is converted into a fixed point value (by multiplying it by 65536), or the fixed point value is converted into an integer (by dividing it by 65536, with a risk of precision loss).
Multiplication works logically between an integer and a fixed point unit.
Dividing a fixed point unit by an integer works logically (2.5 / 10 = 0.25), however dividing an integer by a fixed point unit will not (10 / 2.5 = 0). To divide an integer by a fixed point value, first convert it to fixed point by multiplying it by 65536. The result of the operation will be an integer (10.0 / 2.5 = 4, not 4.0).
With a fixed point valueEdit
Additions and subtractions work logically. Multiplication require a division by 65536, overflows are likely to happen with large values. Divisions require a multiplication by 65536 in order to yield a fixed point result. Convenience functions FixedMul and FixedDiv exist in the source code.