Instead of using >> and << to shift, is it posible to use * and / to shift left and right?
for an 8-bit: 0x01*2 = 0000|0010?
Instead of using >> and << to shift, is it posible to use * and / to shift left and right?
for an 8-bit: 0x01*2 = 0000|0010?
You could, but it would be a smart compiler to optimize this into actual bit shifts! Also, if you mean "shift" you better write <<. When you mean 'multiply', write *.
Note that floating points will not shift at all: their exponent will just grow.
Yes, you can. Taking your example:
int main() {
if ((1*2) == (1 << 1)) printf("you certainly can!\n");
else printf("doesn't work that way\n");
}
And the output it produces:
you certainly can!
See the comments to this response as to why we agreed that (0x01*2 == 0000|0010) is FAR more problematic than ((1*2) == (1 << 1)), a much more concise version.
You can of course (for integer math) use multiply by two for a left shift, and a divide by two for a right shift.
You shouldn't do it though.
There are perfectly good left shift and right shift operators, and they do "exactly what they say on the tin". Why confuse your compiler or anyone else reading your code by doing otherwise?
You should avoid shifting in all cases except when you do bit-operations. Writing << instead of * 2 makes the code less legible. Don't use bit-shifting unless you explicitly want to.
Compilers optimize *2
n to <<
anyway.
You can, but why would you want to? Shifting operations are among the things a CPU can do most quickly.
Actually, the opposite is often suggested as a performance optimization: Using shifts to implement multiplication/division by a power of 2.
But any half-decent compiler will do that for you, so you should absolutely not do it manually: keeping your code clear is the most important thing, so use multiplication and division if you're doing math, and use bit shifts if you're manipulating bits.
You can,
x << 1 == x * 2
x << 2 == x * 4
etc...
and conversly
x >> 1 == x / 2
x >> 2 == x / 4
etc...
Although I would argue than an experienced c-programmer should be able to look at a bit shifting operation and know that the two methods are analogous. Given the choice I would always use bit shifting as it is clear what your intentions are. If you did use the multiplication / or division option you would clearly need to comment why you are suddenly multiplying values by seemingly random numbers. Whereas the bit shifting clearly documents that you are trying to shift bits.
As for any optamization comments, unless absolutely necessary e.g. time critical emebedded programming, I wouldn't overly worry about optamization of your code. Code readability and maintainability should be your focus, not optamization! If at the end of development, you need more performance, you can always go back and do the optamization (making sure you carefyully document eveverything you do!). But during development, I would go for what is the easiest to read and maintain e.g. using '<<' / '>>'.
Yes, except for one gotcha: division may work differently to right shifting when dealing with negative numbers. The behaviour of right shifts on negative numbers is compiler defined.
You can of course avoid this issue by using unsigned integers.
As others have said, a modern compiler will probably produce the same output whether you use shifts or multiplication/division. So use whatever makes the code easier to follow and maintain.
All others have said it's perfectly possible to do. It's also pointless. If you mean to shift then shift. If you mean to multiply then multiply. Don't confuse the reader of your code with useless "optimization".
An aside from the Question:
Your compiler will look at any integer multiply/divide by a constant amount and reduce the expression to a series of shift/add operations almost all of the time. It does this because binary multiplication is not an easy task, and it takes a lot longer than shifts and adds, which can be completed in a singe clock cycle once they are passed into the ALU. Interesting the integer multiplier in a CPU does roughly similar but in an automated way - it's still slightly faster to use individual shift/add operations because you don't need to stop and test conditions for every level of shifting you're doing.
I could draft the basic algorithm into here for you, but it's nearly midnight so you can google it. If there's enough call for it I'll edit the post and put it in tomorrow.
This optimization is particularly true of multiplies by constants of the 2^n variety, because it's a single shift operation.
Yes you can always replace shifts with power of 2 multiplications but as has been pointed out, why?. What hasn't been pointed out is that it is sometimes useful to replace multiplication with shifting and not just for simple powers of 2. For example in the good ol' days with 320 * 200 pixel buffers the offset to a pixel byte was y*320+x. This could be done as follows:
int OffsetXY( int x, int y)
{
int offset;
y <<= 6;
offset = y;
offset += y << 2; // offset = original y * 320
return offset + x;
}
While this sort of is only of academic interest to most developers now, it can be useful in the embedded world (did some coding recently on the DS and this kind of thing was useful).