除非您的 CPU 出现某种缺陷,否则您只需使用mul 命令:-)
但是,在一般意义上,您只需要注意乘法是重复加法,因此4 x 7 是 7 批 4 加在一起:4 + 4 + 4 + 4 + 4 + 4 + 4。
所以这种野兽的简单伪代码是:
def mul(unsigned a, unsigned b): # line 1
res = 0 # line 2
while b > 0: # line 3
res = res + a # line 4
b = b - 1 # line 5
return res # line 6
在示例试运行中使用您的测试数据显示了它是如何工作的:
Line# a b res
----- --- --- ---
1 5 2 ?
2 0
3 (b>0, keep going)
4 5
5 1
3 (b>0, keep going)
4 10
5 0
3 (b==0, exit loop)
6 (returns 10)
请注意,这仅使用无符号值,您只需稍作修改即可处理有符号值:
def mul(int a, int b):
sign = 1
if a < 0:
a = -a
sign = -sign
if b < 0:
b = -b
sign = -sign
res = 0
while a > 0:
res = res + b
a = a - 1
if sign == -1:
res = -res
return res
还请记住,实际上有更有效的乘法方法涉及值的位移(最小化所需的加法),而不是简单的重复加法。
我的意思是像9999 x 9999 这样的计算将使用简单的方法执行大约 10,000 次加法。通过使用移位,您可以将其中一个数字的每个数字所需的加法限制为 9 个,而另一个数字的每个数字只需不到 1 个,这意味着您可以在上述计算中进行大约 40 个加法。
当您意识到可以将9999 x 9999 简化为:
9999 x 9 -> nine additions
+ 99990 x 9 -> nine additions
+ 999900 x 9 -> nine additions
+ 9999000 x 9 -> nine additions
\____________/
|
V
three additions
如果您想更详细地了解移位的工作原理,维基百科有一个 article on the topic。
顺便说一句,当您乘以一个常数时,您可以获得相当不错的性能,因为您事先知道需要执行哪些操作。例如,将寄存器乘以 10 可以通过以下方式完成(请记住,我的组装时间已经过去很久了):
mul_ax_by_10: push bx ; save registers
shl ax ; ax <- orig_ax * 2
push ax ; save for later add
shl ax
shl ax ; ax <- orig_ax * 8
pop bx ; bx <- orig_ax * 2
add ax, bx ; ax <- (orig_ax * 8) + (orig_ax * 2)
; <- orig_ax * (8 + 2)
; <- orig_ax * 10
pop bx ; restore saved register
ret ; result in ax