我正在为一台名为AIDJ的虚拟计算机编写一个乘法程序。
它支持任意数量的变量,并且能够读取和执行表单的任何操作序列(程序)
mk: <operation>
mk 是标记, 只能取自:
Increment: x(i) = x(i) + 1
Decrement: x(i) = x(i) - 1
Conditional Jump: if x!=0 goto <mk>
Assignment: x(i) = c (where c is any natural number)
除了可能的条件跳转之外 - AIDJ按程序描述的顺序评估操作,并在程序完全处理时停止。
以节目ADD 为例,c> = 1 :
00: x(1) = c
01: x(2) = d
02: x(2) = x(2) + 1
03: x(1) = x(1) - 1
04: if x(1) != 0 goto 02
以节目MULTIPLY 为例,其中c> = 2 :
00: x(1) = d
01: x(1) = d - 1
02: x(2) = c
03: x(3) = c
04: x(2) = x(2) + 1
05: x(3) = x(3) - 1
06: if x(3) =! 0 goto 04
07: x(1) = d - 1
08: if x(3) =! 0 goto 03
我确保c×d等于c + c + ... + c(d加法)所以我可以使用程序ADD,并确保ADD执行d-1次。当计算停止时,x(2)等于c×d。
如果 c = 3且d = 3 ,则会生成以下值表:
| Command | x(1) | x(2) | x(3) |
--------------------------------------------------
| 00: x(1) = d | 3 | - | - |
| 01: x(1) = d - 1 | 2 | - | - |
| 02: x(2) = c | 2 | 3 | - |
| 03: x(3) = c | 2 | 3 | 3 |
| 04: x(2) = c + 1 | 2 | 4 | 3 |
| 05: x(3) = d - 1 | 2 | 4 | 2 |
| 06: if x(3) =! 0 goto 04 | 2 | 4 | 2 |
| 04: x(2) = c + 1 | 2 | 5 | 2 |
| 05: x(3) = d - 1 | 2 | 5 | 1 |
| 06: if x(3) =! 0 goto 04 | 2 | 5 | 1 |
| 04: x(2) = c + 1 | 2 | 6 | 1 |
| 05: x(3) = d - 1 | 2 | 6 | 0 |
| 06: if x(3) =! 0 goto 04 | 2 | 6 | 0 |
| 07: x(1) = d - 1 | 1 | 6 | 0 |
| 08: if x(3) =! 0 goto 03 | 1 | 6 | 0 |
| 03: x(3) = c | 1 | 6 | 3 |
| 04: x(2) = c + 1 | 1 | 7 | 3 |
| 05: x(3) = d - 1 | 1 | 7 | 2 |
| 06: if x(3) =! 0 goto 04 | 1 | 7 | 2 |
| 04: x(2) = c + 1 | 1 | 8 | 2 |
| 05: x(3) = d - 1 | 1 | 9 | 1 |
| 06: if x(3) =! 0 goto 04 | 1 | 9 | 1 |
| 04: x(2) = c + 1 | 1 | 9 | 1 |
| 05: x(3) = d - 1 | 1 | 9 | 0 |
| 06: if x(3) =! 0 goto 04 | 1 | 9 | 0 |
| 07: x(1) = d - 1 | 0 | 9 | 0 |
| 08: if x(3) =! 0 goto 03 | 0 | 9 | 0 |
我如何更改上述程序,使其除以而不是乘法?
答案 0 :(得分:4)
Multyplying正在循环中添加,对吗?好吧,除法是在一个循环中减去,直到被除数的剩余部分小于除数。在伪代码中:
# We're dividing a/b, getting the quotient c
c = 0
while a >= b
{
a = a - b
c = c+1
}
# End of loop
# The value of a is the remainder at this point
所以顺便说一句。首先,实现减法(在VM上循环递减)。然后做其余的事。
由于条件仅限于与零进行比较,因此通过减法(循环中的减量)实现&gt; = b的逻辑。并且不要害怕引入额外的变量。架构可能会发育不良,但对使用的内存没有明确的限制,是吗?
您甚至可以将循环条件(循环中的减量)与循环体(也是循环中的减量)组合在一起。这不是他们在高级语言中如何做到这一点,甚至不是真正的CPU如何做到这一点 - 所有现代CPU都将整数比较作为基元。 “减量,如果在除数的剩余部分达到零之前达到零,那么就会出现”,然后退出循环,我们就完成了“。然而,在现实生活中,强烈建议采用这种微观优化(对于不存在的架构,不能少)。
另外,如果这是作业,请添加“家庭作业”标签。闻起来很像我的作业。
编辑:这是逻辑。我们引入了三个变量:使用与VM原语对应的伪代码。你把它翻译成AIDJ语法 - 我的意思是,你必须在这里做至少一些工作。 #标记评论。标签(即转到目的地)标有:
x(1) = d
x(2) = 0
x(3) = c
Main_Loop:
x(1) = x(1) - 1 # decrement the running copy of the dividend
x(3) = x(3) - 1 # decrement the running copy of the divisor
if x(3) != 0 goto Divisor_still_nonzero
# If we're here, this means we've reached the end of the divisor.
# Increment the quotient, reset the running divisor to the initial value
x(2) = x(2) + 1
x(3) = c
Divisor_still_nonzero:
# Now let's check if we've reached the zero on the dividend
if x(1) != 0 then goto Main_Loop
# If x(1) is zero then we end up here.
# Means we've exhausted the dividend.
# Now the value of x(2) is the quotient.
# The remainder is c minus x(3),
# but retrieving it was not a requirement.
在现实生活中,你还应该在一开始就检查c和d是零还是负数。如果d为零,则代码将中断 - 它将在第一次迭代时变为负数,并且仅在变量受溢出时才终止。如果c为零,则整个分区是非法的。
还需要对负片进行额外处理。
另外,请记住,有些教授会观看Stack Overflow。