固定点除以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 loop
中的第2行到第5行实际上正在执行
x*.000111 (in decimal representation x*0.1)
,它在后续while loops
中尝试实现的目标是什么?
不应该再将它与7相乘并再次转换 只做转移来照顾复发?
关于简单十进制数乘法的解释,关于仅通过移位实现的目标将是很好的。
详细代码说明如下: Divide by 9 without using division or multiplication operator
答案 0 :(得分:2)
让我们用字母F+ (F/64) + (F/64^2) + (F/64^3) + (F/64^4)+ (F/64^5) + ...
表示7/64。 7/64以二进制表示为0.000111并且非常接近1/9。但非常接近是不够的。我们想用F来精确到1/9。
它按以下方式完成
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
代码在变量y
中存储F*x*64
变量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
的结果。
答案 1 :(得分:1)
向左移动一个乘以2,向右移动一个除以2。为什么呢?
移位是从数字中取出所有位并将它们n
位向左/右移动的动作。例如:
00101010 is 42 in Binary
42 << 2 means "shift 42 2 bits to the left" the result is
10101000 which is 168 in Binary
we multiplied 42 by 4.
42 >> 2 means "shift 42 2 bits to the right" the result is
00001010 which is 10 in binary (Notice the rightmost bits have been discarded)
we divided 42 by 4.
同样:(x << 3)
为x * 8
,因此(x << 3) - x
为(x * 8) - x
=&gt; x * 7