需要澄清有关此循环执行乘法的信息

Need clarification about this loop performing multiplication

本文关键字:执行 信息 循环      更新时间:2023-10-16
int x, y; // x is a non-negative integer 
p = 0;
while (x > 0)
{
    if ( x % 2 == 1 )
       p = p + y;
    y = y*2;
    x = x/2;
}
// p == a*b here

我知道这个循环使用代数找到"a"和"b"的乘积:

a *

b = (1/2(a * 2b

但我不明白代码:

if ( x % 2 == 1 )
    p = p + y;

我希望有人能解释为什么"p"在x的奇数值上被分配为"p + y"。

while (x > 0) {
    if (x % 2 == 1)
        p = p + y;
    y = y*2;
    x = x/2;
}

想象一下x = 4,y = 5

迭 代:

  1. x是偶数,y = 10,x = 2(即 x可以除,y应该加倍(
  2. x为偶数,y = 20,x = 1
  3. x是奇数,p = 20,y = 40,x = 0(即 x不能再除,y应该加到p
  4. (
  5. x > 0 false,循环结束

p = 4 * y

现在想象一下x开始时是奇数,假设 x = 5,y = 2:

  1. x是奇数,p = 2,y = 4,x = 2
    (5/2 = 2.5,x的新值将向下舍入,y应在加倍之前添加(
  2. x为偶数,y = 8,x = 1
  3. x为奇数,p = 10,y = 16,x = 0

p = y + 4* y

第一个y是原因,在加倍(1 * y(之前将其添加到结果中,在这种情况下等价于0.5 * (2 * y)

因为这些是整数,所以a / 2将是整数。如果a是奇数,则该整数已向下舍入,并且在循环的下一次迭代中缺少半b,即循环的当前迭代中b一个整数(因为b [ y ] 每次都翻倍(。

如果 x

是奇数,x = x/2会将 x 设置为小于 x/2 的 0.5(因为整数除法将其向下舍入(。 p需要进行调整以允许这一点。

乘法视为重复加法,x*y 是将 y 加在一起 x 次。这也与将 2*y 加在一起 x/2 次相同。从概念上讲,如果 x 是奇数,这意味着什么还不清楚。例如,如果 x=5 和 y=3,加 2.5 倍是什么意思?代码注意到 x 何时为奇数,将 y 加入,然后执行 y=y*2 和 x=x/2。当 x 为奇数时,这将丢弃 .5 部分。所以在这个例子中,你加一次y,然后x变成2(而不是2.5(,因为整数除法会抛弃分数。

在每个循环结束时,您将看到原始 x 和 y 的乘积等于 p、x 和 y 的当前值的 p + x*y。循环迭代直到 x 为 0,结果完全在 p 中。

如果您创建一个表并每次通过循环更新它,它也有助于查看正在发生的事情。以下是每次迭代开始时的值:

x | y  | p
----------
5 | 3  | 0
2 | 6  | 3
1 | 12 | 3
0 | 24 | 15

这是通过观察(例如(y * 10 = y * 8 + y * 2 .

这就像在学校里在纸上做乘法一样。例如,要乘以 14 x 21,我们一次乘以一位数字(并在需要时向左移动(,因此我们添加 1x14 + 2 x 14(向左移动一位数字(。

    14
  x 21
  ----
    14
   280

在这里,我们正在做几乎相同的事情,但以二进制而不是十进制工作。右移与数字奇数无关,而与简单地找到数字中的哪些位被设置有关。

当我们向右移动一个操作数以

查找是否设置了位时,我们也将另一个操作数向左移动,就像我们在纸上以十进制算术时将数字向左移动一样。

因此,以二进制方式查看事物,我们最终会得到如下结果:

      101101
    x  11010
    --------
     1011010
+  101101000
+ 1011010000
如果我们愿意,我们可以向左移动掩码,而不是向

右移动操作数,这样我们就不用反复and 1,而是用1 and,然后用2,然后用4,依此类推(事实上,这样可能更有意义(。然而,无论好坏,在汇编语言中(通常执行这种事情(,移动操作数并为掩码使用常量通常比在寄存器中加载掩码并在需要时移动它要容易一些。

你应该将 x 重写为 2*b+1(假设 x 是奇数(。然后

x*y = (2*b+1)*y = (2*b)*y + y = b*(2*y) + y = (x/2)*(2*y) + y

其中 (x/2( 表示整数除法。以这种方式重写操作后,您会看到 x/2、2y 和 +y 出现。