3 ms·
It's not exactly rocket science, here's a simplified explanation (minus some subtleties): You're trying to calculate n/d (and the result should be rounded off
by pmjordan 17y ago
It's not exactly rocket science, here's a simplified explanation (minus some subtleties):
You're trying to calculate n/d (and the result should be rounded off to the nearest integer[1]). Division is expensive, but you observe that you can divide by a power of 2 cheaply using a shift instruction, so you decide to transform the calculation into something of the form (n * d')/(2^N), which is a multiply and a shift-right instruction. For the two forms to be equivalent, d' = 2^N / d, which you precompute.
Certain values of N can be more convenient from a computational point of view - for example, multiplying 2 32-bit integers yields a 64-bit result; on most architectures, the high and low halves either land in separate 32-bit registers, or you have to calculate each half with a separate instruction. So if you choose N=32, you don't even need a shift instruction: you simply drop the low bits.
You also need to make sure you choose your d' such that your rounding will be correct for all values of n.
Depending on the exact value of d', it may also be possible to decompose the multiplication further, leaving only shifts and additions/subtractions.
[1] Of course, for floating-point numbers, you can just calculate 1/d, save it and multiply by it any time you need to divide by d.