以下是引用zklhp在2012-4-14 19:36:38的发言:
编译器开优化的情况下会在程序编译的时候把这几个数算出来 所以你会看到优化过的程序直接把这几个数打出来 这是最优化的方法
因为这里程序在运行前就已经知道这几个数的值了 所以可以用上面的优化方法
如果要通用性 考虑以下方法
1 用移位操作代替除以2的整数次幂的运算 比如除以2 4 8 16等等 当然这里不能用。。
2 如果是除数的范围已知的考虑用乘法代替除法 具体百度一下你就知道
3 算法优化
上面说的开优化的情况是一种理想的状况 不过一般的编译器都能做这样的优化了 如果不能你找他们。。
考虑你狠可能不会去百度我给你帖一段罢
除数是常量的除法可以用乘以倒数来做。 为了计算无符号整型除法q=x/d,可以先计算除数的倒数f=2^r/d,这里的r定义了二进制小数点的位置(基点)。 然后把x与f相乘再右移r位即可。 r的最大值是32+b,b是d的有效二进制位的位数-1(即b是满足2^b<=d的最大整数)。 用了r=32+b就可以覆盖被除数x的最大范围。
为了弥补舍入造成的误差,上面的算法还需要做一些细分的操作。 因此下面的方法用了取整操作,得到了无符号整数除法的正确结果,它的结果与DIV指令给出的结果是一致的(感谢 Terje Mathisen 发明了这个方法):
b = (d的有效位位数) - 1
r = 32 + b
f = 2^r / d
如果f是一个整数,那么可以判断d是2的幂次:case A。
如果f不是整数,那么看f的小数部分是否 < 0.5 :f的小数部分 < 0.5,case B;f的小数部分> 0.5 ,case C。
case A: (d = 2^b)
结果 = x SHR b
case B: (f的小数部分 < 0.5)
把f向下取整,然后
结果 = ((x+1) * f) SHR r
case C: (f的小数部分 > 0.5)
把f向上取整,然后
结果 = (x * f) SHR r
示例:
假定除数是5,
5 = 00000101b。
b = (有效位位数) - 1 = 2
r = 32+2 = 34
f = 2^34 / 5 = 3435973836.8 = 0CCCCCCCC.CCC... (十六进制)
f的小数部分大于0。5,进入case C,f向上取整得到0CCCCCCCDh。
类似的例子还有很多
上面漏了一个 还有一种优化方法是改成浮点运算 但会带来其他问题 不推荐
这里主要优化的是除法 因为除法的用时大约比是加 减或乘大一个数量级 不过在这里可以说没有区别 差的那几十个时钟周期应该是纳秒级罢 你能感觉出来么