C语言如何用移位来解决乘除法问题
用移位来解决乘除法问题
a=a*4;
b=b/4;
可以改为:
a=a< < 2;
b=b >>2;
通常如果需要乘以或除以2的n次方,都可以用移位的方法代替。用移位的方法得到代码比调用乘除法子程序生成的代码效率高。实际上,只要是乘以或除以一个整数,均可以想办法用移位的方法得到结果,如:
a=a*9
可以改为:
a=(a< < 3)+a
采用运算量更小的表达式替换原来的表达式,下面是一个经典例子:
原代码:
x = w % 8;
y = pow(x, 2.0);
z = y * 33;
for (i = 0;i < MAX;i++)
{
    h = 14 * i;
    printf("%d", h);
}
修改为:
x = w & 7;                 /* 位操作比求余运算快*/
y = x * x;                 /* 乘法比平方运算快*/
z = (y < < 5) + y;          /* 位移乘法比乘法快 */
for (i = h = 0; i < MAX; i++)
{
    h += 14;               /* 加法比乘法快 */
    printf("%d",h);
}
如此,对比一下执行时间会快很多。
学会避免不必要的整数除法
整数除法是整数运算中最慢的,所以应该尽可能避免。一种可能减少整数除法的地方是连除,这里除法可以由乘法代替。这个替换的副作用是有可能在算乘积时会溢出或者丢失精度,所以只能在一定范围的除法中使用。
举个例子,不好的代码:
int i, j, k, m;
m = i / j / k;
推荐的代码: 注意精度
int i, j, k, m;
m = i / (j * k);
1.1乘法的位移方法
乘法,2的整数倍直接移位
a = b * 4;
a = b<<2;
1
2
  非整数倍也可以拆成整数倍的移位相加
a = b * 5;
a = (b<<2) + (b<<0);
1
2
1.2除法的位移方法
除法,2的整数倍直接移位
a = a / 4;
a = a >> 2;
1
2
  非2的整数倍需要变换一下,算法精度和放大的倍数有关,下面的例子是0x400000。
  原理是用一个远远大于除数,并且是2的整数倍的数,先乘再除,除数被消除变成乘数,后面的除法是2的倍数可以直接位移,这样就把非2整除法变成了乘法和可以位移的2整除法
a/3600 
= a * 0x400000 /3600 / 0x400000 
= a * (0x400000 /3600) / 0x400000 
= a *  1165 >> 22
= a *  0b10010001101 >> 22
= ((a << 10) + (a << 7) + (a << 3) + (a << 2) + (a << 0))>>22
= (a >> 12) + (a >> 15) + (a >> 19) + (a >> 20) + (a >> 22)
1
2
3
4
5
6
7
1.3取模的位移方法
取模,即被除数减去除数和商的积
a % 8
= a - a/8*8
= a - (a>>8<<8)
1
2
3
1.4浮点运算的位移方法
浮点,适用于常量,直接定义被放大后的小数,运算完成后再缩小
#define pi (3.14*256)
a * 3.14
= a * pi >> 8
————————————————
版权声明:本文为CSDN博主「来碗豆腐脑」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/a1058191679/article/details/123984158
                    
                
                
            
        
浙公网安备 33010602011771号