I know with normal integers you can divide by bitshifting to the right. I'm wondering if theres an easy way to do the same with numbers that aren't perfect integers.
-
How would you divide 221/13 by bit shifting to the right? – Martin R Apr 12 '14 at 07:36
-
You mean *powers* of two, right? – user2357112 Apr 12 '14 at 07:36
-
`13` isn't a multiple of `2` (nor a power of `2`, which I think is what he meant) – M.M Apr 12 '14 at 07:37
-
powers of 2. don't know why I wrote multiple, guess fatigue is setting in – user3525846 Apr 12 '14 at 07:38
-
Check [this](http://stackoverflow.com/questions/7720668/fast-multiplication-division-by-2-for-floats-and-doubles-c-c) answer. I hope most of the compilers already do good work for constants. – Mohit Jain Apr 12 '14 at 07:43
3 Answers
ldexp
, ldexpf
, and ldexpl
do this for doubles, floats, and long doubles respectively. Alternatively, if you have a specific power of two in mind (say, 4), it's probably best to just divide the usual way:
whatever / 4

- 260,549
- 28
- 431
- 505
There is a function ldexp
(and siblings) that allows you to "multiply by powers of two" (including negative ones), this is not the same optimisation as using shifts for integers. For powers of two, all double values are "perfect" for both X and 1/X (because if X is 2n, then 1/X = 2-n, both of which are fine to store as a floating point number in IEEE-754 or any other binary floating point format), so there won't be any odd rounding, which means the compiler should be able to replace the divide by a multiply operation - in my experiments, it indeed does.
To manipulate the exponent of floating point values is generally detrimental to performance compared to the "apply multiply by 1/X".
The function ldexp
is a few dozen instructions long in glibc, with several branches and a call in the code. It is highly unlikely you'll find any benefit from calling ldexp
, as well as confusing people who don't know that x = ldexp(x, -1);
is the same as x /= 2.0;
.

- 126,704
- 14
- 140
- 227
Just use
double x = 7;
x *= 2;
x /= 2;
assert(x == 7.0);
or
double y = 5;
y = 2*x + 0.5*y;
assert(y == 16.5);
or
double z = 2.5*x;
assert(z == 17.5);
Why? Because your computer can represent all powers of two as floating point values (as long as that power does not exceed the limit of the exponent, that is), and it will do so. Consequently, all of the calculations above are precise, there is no rounding error in the constants. All the assert()
s are guaranteed to succeed.
Of course, you can achieve the same effect by doing bit manipulations, but current floating point hardware can do a multiplication within a nanosecond, and it handles all special cases correctly. If you do the bit fiddling, you will either waste time, or handle the special cases incorrectly. So don't even try.

- 38,891
- 9
- 62
- 106