定点除以9的代码。
1. q = 0; // quotient
2. y = (x << 3) - x; // y = x * 7
3. while(y) { // until nothing significant
4. q += y; // add (effectively) binary 0.000111
5. y >>= 6; // realign
6. }
7. q >>= 6; // align
while 循环
的第一次执行中的第 2 行到第 5 行有效
x*.000111(十进制表示 x*0.1)
,它在后续的 while 循环
中试图实现什么?
它不应该再次乘以 7 并再次移动吗 只做转移以照顾复发?
关于纯十进制数乘法的解释,即仅通过移位实现的效果会很好。
详细代码解释在这里: Divide by 9 without using division or multiplication operator
最佳答案
让字母 F
表示 7/64。 7/64 在二进制中表示为 0.000111,非常接近 1/9。但非常接近是不够的。我们想用 F 精确到 1/9。
它是通过以下方式完成的
F+ (F/64) + (F/64^2) + (F/64^3) + (F/64^4)+ (F/64^5) + ...
随着我们向这个序列中添加更多元素,结果会越来越接近 1/9
请注意,序列中的每个元素恰好是前一个元素的 1/64
。
除以 64 的快速方法是 >>6
您实际上想要构建一个循环来对这个序列求和。您从 F 开始,在每次迭代中执行 F>>6
并将其添加到总和中。
最终(经过足够多的迭代)总和将正好是 1/9
。
现在好了,你已经准备好理解代码了。
代码没有使用 F(这是一个分数,不能用定点表示),而是将 F 乘以 x。
所以序列的总和将是 X/9
而不是 1/9
此外,为了使用固定点,最好存储 64*X*F
,结果将是 64*X/9
。
稍后在求和之后我们可以除以 64 得到 X/9
代码将 F*x*64
的值存储在变量 y
中
变量q
存储序列的总和。在每次循环迭代中,我们通过将前一个元素除以 64 (y>>=6
)
最后在循环之后我们将总和除以 64 (q>>=6
) 并得到结果 X/9
。
关于你的问题。我们不应该每次都乘以 7 否则我们将得到序列的和
F+ (F^2) + (F^3) + (F^4) + (F^5)...
这将产生 ~X/(8+1/7)
而不是 X/9
的结果。
关于c - 定点码分理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30590008/