以下程序计算此表达式的值
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
编写此程序的人没有使用乘法和除法运算符,可能有人向我解释这里真的发生了什么,我的意思是程序中的(*和/)在哪里?为什么或者目的是什么?左右移动?
#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");
}
答案 0 :(得分:6)
二进制数中的每个数字是前一个数字的2倍:
1 Binary = 1 Decimal
10 Binary = 2 Decimal
100 Binary = 4 decimal
1000 Binary = 8 decimal
因此,如果将位1向左移位数字,则相当于乘以2.
相反地将1个位置向右移动就像是除以2。
如果您移动多个位置,则只需增加2的幂。因此,将n
位置向左移动就像乘以2^n
一样,将n
位置向右移动就像除以2^n
等。
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
绝对没有理由这样做。
事实上,我会说在normal
情况下这是一种可怕且完全不好的做法;如果编译器认为这将是一个好处并且缺点(正如您所注意到的那样)会使代码更难以阅读,编译器将自动执行此优化。
如果您知道编译器是坏的并且不这样做那么可能值得做(但可能只是)。
答案 1 :(得分:4)
将整数m
向右移位整数n
只是意味着将m除以2除以n的幂,向左除以将它们相乘
所以i / 16
相当于i >> 4
,因为2^4
是16
,其余的表达式如下:)
答案 2 :(得分:1)
正如其他人所提到的,位移是另一种乘以或除以2的幂的方法。对于除法,重要的是要记住它正在进行整数除法,也就是说,余数将会丢失。
你想要做这样的事情的原因是因为速度。 CPU可以比它的乘法更快地进行位移。但是,虽然我不是这方面的专家,但我必须相信你的编译器无论如何都会进行优化,因此我不建议仅仅因为这个原因而降低代码的可读性。 :)