Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between bit shifting and arithmetical operations?

int aNumber;

aNumber = aValue / 2;
aNumber = aValue >> 1;

aNumber = aValue * 2;
aNumber = aValue << 1;

aNumber = aValue / 4;
aNumber = aValue >> 2;

aNumber = aValue * 8;
aNumber = aValue << 3;

// etc.

Whats is the "best" way to do operations? When is better to use bit shifting?

like image 344
emenegro Avatar asked Jun 07 '10 07:06

emenegro


People also ask

What is the difference between arithmetic and logical shift operations?

Logical shift treats the number as a bunch of bits, and shifts in zeros. This is the >> operator in C. Arithmetic shift treats the number as a signed integer (in 2s complement), and "retains" the topmost bit, shifting in zeros if the topmost bit was 0, and ones if it was one.

What is arithmetic shifting operation?

Arithmetic : This micro-operation shifts a signed binary number to the left or to the right position. In an arithmetic shift-left, it multiplies a signed binary number by 2 and In an arithmetic shift-right, it divides the number by 2.

What are the differences between arithmetic shift right and shift right operation?

If a number is encoded using two's complement, then an arithmetic right shift preserves the number's sign, while a logical right shift makes the number positive.

What is an arithmetic binary shift?

An arithmetic shift in computer science involves a bitwise operation shifting binary numbers to an adjacent position, or some other position, either right or left. Arithmetic shifts can help perform multiplication or division on binary numbers.


2 Answers

The two are functionally equivalent in the examples you gave (except for the final one, which ought to read aValue * 8 == aValue << 3), if you are using positive integers. This is only the case when multiplying or dividing by powers of 2.

Bit shifting is never slower than arithmetic. Depending on your compiler, the arithmetic version may be compiled down to the bit-shifting version, in which case they both be as efficient. Otherwise, bit-shifting should be significantly faster than arithmetic.

The arithmetic version is often more readable, however. Consequently, I use the arithmetic version in almost all cases, and only use bit shifting if profiling reveals that the statement is in a bottleneck:

Programs should be written for people to read, and only incidentally for machines to execute.

like image 172
fmark Avatar answered Nov 15 '22 20:11

fmark


The difference is that arithmetic operations have clearly defined results (unless they run into signed overflow that is). Shift operations don't have defined results in many cases. They are clearly defined for unsigned types in both C and C++, but with signed types things quickly get tricky.

In C++ language the arithmetical meaning of left-shift << for signed types is not defined. It just shifts bits, filling with zeros on the right. What it means in arithmetical sense depends on the signed representation used by the platform. Virtually the same is true for right-shift >> operator. Right-shifting negative values leads to implementation-defined results.

In C language things are defined slightly differently. Left-shifting negative values is impossible: it leads to undefined behavior. Right-shifting negative values leads to implementation-defined results.

On most practical implementations each single right-shift performs division by 2 with rounding towards negative infinity. This, BTW, is notably different from the arithmetic division / by 2, since typically (and always in C99) of the time it will round towards 0.

As for when you should use bit-shifting... Bit-shifting is for operations that work on bits. Bit-shifting operators are very rarely used as a replacement for arithmetic operators (for example, you should never use shifts to perform multiplication/division by constant).

like image 31
AnT Avatar answered Nov 15 '22 18:11

AnT