需要澄清有关此循环执行乘法的信息
Need clarification about this loop performing multiplication
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
迭 代:
-
x
是偶数,y
= 10,x
= 2(即x
可以除,y
应该加倍( -
x
为偶数,y
= 20,x
= 1 -
x
是奇数,p
= 20,y
= 40,x
= 0(即x
不能再除,y
应该加到p
( -
x > 0
false
,循环结束
p
= 4 *y
现在想象一下x
开始时是奇数,假设 x
= 5,y
= 2:
-
x
是奇数,p
= 2,y
= 4,x
= 2
(5/2 = 2.5,x
的新值将向下舍入,y
应在加倍之前添加( -
x
为偶数,y
= 8,x
= 1 -
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/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 出现。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 正在查找文档以获得PS4平台的C++中的设备信息
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 执行函数时导致崩溃的变量
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 该代码注入第三方Qt应用程序并执行一些方法来获取Qt应用程序信息
- Qt 和 Windows 可执行版本信息
- 双击编译C++ Unix 可执行文件不会打开现有文件以从中读取信息
- 单步执行,直到退出没有行号信息的函数__svfscanf_l
- 需要澄清有关此循环执行乘法的信息
- 关于可执行文件的标识信息
- CUDA insight -保存有关内核执行的信息到excel文件
- Lua & C++ API 获取执行信息