c - 定点码分理解

标签 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 循环 的第一次执行中的第 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/

相关文章:

math - 计算矩阵的 k 次幂的迹

python - 当分离 < 1 px 时在 python 中使用 PIL 检测图像形状边缘的算法

c - 如何将整数的输入限制为2-12?

java - 在 Java 中实现归并排序 : Only zeroes

c - 错误未定义对库的引用

java - 存储项目到项目关联的算法

algorithm - 公式中的智能求和)翻译)

ruby - 什么是 Numeric#arg 和 Numeric#angle?

javascript - 获取命令行参数

c - 在 C 语言中使用 If else 处理 Char