kryticrecte
kryticrecte

Reputation: 377

understanding operator and bit shifts in c

the program below computes the value of this expression below

m = i /16 + j *128-17 + k *2- l /32 , if i > j + 2 * k else 
m = i /16 + j *128-17 + k *2 + l /32

the person who wrote this program did not use multiplication and division operators,may somebody explain to me whats really going on here,i mean where are the( * and /) in the program?why or what is the purpose of the shifting right and left?

#include <stdio.h>
#include <cstdlib>

int main(){
    unsigned int i, j, k, l, m;
    printf("i = "); scanf("%d", &i);
    printf("j = "); scanf("%d", &j);
    printf("k = "); scanf("%d", &k);
    printf("l = "); scanf("%d", &l);
    if (i > j + (k << 1)) 
        m = (i >> 4) + (j << 7) - 17 + (k << 1) - (l >> 5);
    else
        m = (i >> 4) + (j << 7) - 17 + (k << 1) + (l >> 5);
    printf("m = %d\n", m);
    system("pause");
}

Upvotes: 1

Views: 146

Answers (3)

Loki Astari
Loki Astari

Reputation: 264331

Each digit in a binary number is 2 times the previous digit:

   1    Binary = 1 Decimal
  10    Binary = 2 Decimal
 100    Binary = 4 decimal
1000    Binary = 8 decimal

Thus if you shift the bits 1 place to the left in a number it is equivalent to multiplying by 2.

Conversely shifting 1 place to the right is like dividing by 2.

If you shift multiple places you just increase by a power of 2. Thus shifting n places to the left is like multiplying by 2^n and shifting n places to the right is like dividing by 2^n etc.

   i / 16
=> i / (2^4) 
=> 1 >> 4      // division right shift

   j * 128
=> j * (2^7)
=> j << 7      // multiplication left shift

   k * 2
=> k * (2^1)
=> k << 1      // multiplication left shift

   l / 32
=> 1 / (2^5) 
=> l >> 5      // division right shift

There is absolutely no reason to do this.
In fact I would say it is a terrible and completely bad practice in normal situations; the compiler will automatically do this optimization if it thinks it will be a benefit and the downside (as you have noticed) is that it makes the code much harder to read.

If you know the compiler is bad and does not do this then maybe it is worth doing (but only maybe).

Upvotes: 6

Wesley Petrowski
Wesley Petrowski

Reputation: 1131

As other people have mentioned, bit shifting is another way to multiply or divide by powers of 2. For division, it's important to remember that it is doing integer division, that is, the remainder will be lost.

The reason why you would want to do something like this is because of speed. A CPU can do a bit shift much faster than it can do a multiply. However, though I'm not an expert in the subject, I've got to believe your compiler would make that optimization anyway, and therefore I wouldn't recommend decreasing the readability of your code just for this reason. :)

Upvotes: 1

Andreas Wong
Andreas Wong

Reputation: 60506

bit shifting an integer m to the right by integer n simply means dividing m by two to the power of n, to the left means multiplying them

So i / 16 is equivalent to i >> 4 as 2^4 is 16, the rest of the expression follows :)

Upvotes: 4

Related Questions