倒数相乘
编译器会对除数已知
的除法
进行优化,使用倒数相乘
和移位
的方法,用消耗时钟周期数少的imul和mul
指令代替div和idiv
指令。如x/3会被编译器优化成1*3-1。
当倒数的小数部分的前面有太多0时,编译器会选择将倒数左移n位,乘法计算完成之后再将计算结果右移n位。此处,编译器会选择n的长度,从而保证后面的位数舍弃时,造成的影响最小
。
测试代码
由于没办法确定编译器“保证后面的位数舍弃时,造成的影响最小”的定义,这里提供一种由除数Divisor得到Magic Number和右移位数
的思路的算法:
def DealDivision(Divisor):
if Divisor<=1:
print("Input Error !")
return -1
#初始化右移次数
RightShiftCount=0
#除去除数中的因子2
while Divisor%2==0:
Divisor//=2
RightShiftCount+=1
#取倒数
Result=1/Divisor
#除去小数点后的大部分0
while (Result*16)<1:
Result*=16
RightShiftCount+=4
#取小数点后的32位
Result=int(Result*(2**32))
#输出
print("Magic Number: 0x%X"%Result)
print("RightShiftBits: %d"%RightShiftCount)
if __name__ == '__main__':
try:
Divisor=int(input("Please input a integered divisor above 1: "))
DealDivision(Divisor)
except ValueError:
print("Inpur Error !")
验证
测试程序
#include <iostream>
using namespace std;
int main()
{
int n = 10010;
n += rand();
n /= 1001;
cout << n << endl;
return 0;
}