| re: Bit-shifting to multiply and divide?
Method Man wrote:[color=blue]
> "Nobody" <nobody@cox.net> wrote in message
> news:kaQld.93842$G15.28203@fed1read03...
>[color=green]
>>I have some code that I am trying to optimize for speed...
>>
>>trying to squeeze every last CPU cycle out... I remembered an old trick
>>where dividing & multiplying can be sped up by using bitshifts and
>> addition / subtraction instead[/color][/color]
[...][color=blue][color=green]
>>but is it possible to do this for the division?[/color]
>
> I was once asked in an interview how to efficiently divide by 7 without
> using division. I implemented it like so:
>
> unsigned div7(unsigned x) {
> long temp;
> temp = (x * 293) >> 11; /* 1/7 is approx. equal to 293/2048 */
> return (unsigned int) temp;
> }
>
> I am not sure if this helps (or is 100% correct), but you can use the same
> strategy to divide by 255.[/color]
This works. I personally would write it more like:
unsigned div7(unsigned x)
{
return static_cast<unsigned>(
static_cast<unsigned long>(x * (2048/7)) / 2048);
}
(of course, then this technically uses division... and has *slightly*
higher error due to rounding)
If your compiler doesn't know how to convert multiplication/division by
powers of 2 into bit shifts, you need a better compiler. (are you sure
you had optimizations turned on?)
Division by 7, eg, is a different matter. The range where this method
is valid isn't the same as the range where a simple divide by 7 is
valid, so the compiler will probably not be able to do it automatically.
You're essentially doing a fixed-point multiply by the reciprocal.
-josh |