Reputation: 377
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
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
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
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