简体   繁体   中英

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");
}

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).

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 :)

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. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM