定点代码划分理解

时间:2015-06-02 07:32:11

标签: c algorithm math fixed-point

固定点除以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

2 个答案:

答案 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

相关问题