如何在小人计算机程序中产生股息和余数?
How to produce dividend and remainder in a little man computer program?
我正在尝试编写一个 LMC 程序,它接受两个整数输入,将它们相除,然后产生商和余数。首先,我将问题分为 4 个阶段:
1.Divide num1 除以 num2 得到商,q。
2.Multiply q 和 num2 得到精确的相乘数,存入 num2.
3.Subtract num1 中的 num2,并将答案存储在 rem 中。
4.Output q 和 rem.
这是我写的代码:
INP
STA NUM1
LDA NUM1
STA ORG
INP
STA NUM2
BRZ END
LDA 99
STA Q
LOOP LDA NUM1
BRZ END
LDA NUM1
SUB NUM2
STA NUM1
LDA Q
ADD ONE
STA Q
BRA LOOP
LDA Q
STA NUM3
LDA NUM2
SUB ONE
STA NUM2
LOOP LDA NUM2
BRZ END
LDA NUM3
ADD Q
STA NUM3
LDA NUM2
SUB ONE
STA NUM2
BRA LOOP
LOAD ORG
SUB NUM3
STA REM
END LDA Q
OUT Q
LDA REM
OUT REM
HLT
NUM1 DAT
NUM2 DAT
ORG DAT
Q DAT
ONE DAT 1
TOTAL DAT
NUM3 DAT
REM DAT
当我尝试 运行 LMC 模拟器中的代码时,它没有产生结果,而是无限期地继续计算。我怎样才能让它发挥作用?有一个更好的方法吗?非常感谢任何帮助。
Is there a better way to do this?
您的方法是合乎逻辑的,但可能矫枉过正。单独做除法,当你不能再从被除数中减去除数时停止,将同时产生商和余数。
例如,如果要将 13 除以 4,则 13 减去 4 得到 9,然后 9 减去 4 得到 5,然后 5 减去 4 得到 1,现在我们停止,因为 4 大于1(我们不能不减去负数)。商是我们能够减去 4 的次数(是 3 次),余数是停止后剩下的,这里是 1。
How can I make it work?
至于为什么您的代码会无限循环,可能是因为您只是通过使用 BRZ
来寻找精确的除法。您应该考虑改用 BRP
,这将允许非零余数。您应该在 LMC 调试器中单步执行,看看为什么它不会在您希望的时候停止。
你的程序有几个问题:
OUT
不接受参数。它不应该是 OUT Q
,而只是 OUT
。一个好的LMC模拟器应该会抱怨这个。
LOOP
被定义为标签两次。这是模棱两可的。一个好的LMC模拟器应该会抱怨这个。
BRA LOOP
下方的代码在 END
处的指令之前无法访问。这是死代码。
- 只有当
NUM1
变为零时才能退出循环,但这可能永远不会发生。例如,如果您将 4 除以 5,则减法将产生负溢出,并且累加器将不会为零(实际上它没有由语言定义,然后它会有什么值)。您应该使用 BRP
. 构建循环条件逻辑,而不是在那里使用 BRZ
Q
的初始化取自99号邮箱,但前提是你的程序不占用99号邮箱。这个是对的,不过最好给一个DAT 0
打个标签.
- 没问题,但是不需要第三条指令 (
LDA NUM1
),因为累加器已经有了那个值。
你要实现的算法有点啰嗦。在您从第一个数字中减去第二个数字并且没有更多的减法是可能的之后,您将已经有了余数(如果您做对了)。
您的算法还应该以不同方式处理 0 除数:在这种情况下,可能会输出一些预定义的值以指示商未定义,例如 999。
这里是你如何编码的。这是一个可运行的片段,其中包含一些您可以改编的示例输入:
#input: 19 5
LDA zero # initialise
STA quotient
INP
STA remainder
INP
STA divisor
BRZ error # division by 0 is undefined
loop LDA remainder
SUB divisor
BRP continue
end LDA quotient # output the results
OUT
LDA remainder
OUT
HLT
continue STA remainder
LDA quotient
ADD one
STA quotient
BRA loop
error LDA big # output 999 twice to indicate error
OUT
OUT
HLT
remainder DAT
divisor DAT
quotient DAT
zero DAT 0
one DAT 1
big DAT 999
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.816/lmc.js"></script>
我正在尝试编写一个 LMC 程序,它接受两个整数输入,将它们相除,然后产生商和余数。首先,我将问题分为 4 个阶段:
1.Divide num1 除以 num2 得到商,q。
2.Multiply q 和 num2 得到精确的相乘数,存入 num2.
3.Subtract num1 中的 num2,并将答案存储在 rem 中。
4.Output q 和 rem.
这是我写的代码:
INP
STA NUM1
LDA NUM1
STA ORG
INP
STA NUM2
BRZ END
LDA 99
STA Q
LOOP LDA NUM1
BRZ END
LDA NUM1
SUB NUM2
STA NUM1
LDA Q
ADD ONE
STA Q
BRA LOOP
LDA Q
STA NUM3
LDA NUM2
SUB ONE
STA NUM2
LOOP LDA NUM2
BRZ END
LDA NUM3
ADD Q
STA NUM3
LDA NUM2
SUB ONE
STA NUM2
BRA LOOP
LOAD ORG
SUB NUM3
STA REM
END LDA Q
OUT Q
LDA REM
OUT REM
HLT
NUM1 DAT
NUM2 DAT
ORG DAT
Q DAT
ONE DAT 1
TOTAL DAT
NUM3 DAT
REM DAT
当我尝试 运行 LMC 模拟器中的代码时,它没有产生结果,而是无限期地继续计算。我怎样才能让它发挥作用?有一个更好的方法吗?非常感谢任何帮助。
Is there a better way to do this?
您的方法是合乎逻辑的,但可能矫枉过正。单独做除法,当你不能再从被除数中减去除数时停止,将同时产生商和余数。
例如,如果要将 13 除以 4,则 13 减去 4 得到 9,然后 9 减去 4 得到 5,然后 5 减去 4 得到 1,现在我们停止,因为 4 大于1(我们不能不减去负数)。商是我们能够减去 4 的次数(是 3 次),余数是停止后剩下的,这里是 1。
How can I make it work?
至于为什么您的代码会无限循环,可能是因为您只是通过使用 BRZ
来寻找精确的除法。您应该考虑改用 BRP
,这将允许非零余数。您应该在 LMC 调试器中单步执行,看看为什么它不会在您希望的时候停止。
你的程序有几个问题:
OUT
不接受参数。它不应该是OUT Q
,而只是OUT
。一个好的LMC模拟器应该会抱怨这个。LOOP
被定义为标签两次。这是模棱两可的。一个好的LMC模拟器应该会抱怨这个。BRA LOOP
下方的代码在END
处的指令之前无法访问。这是死代码。- 只有当
NUM1
变为零时才能退出循环,但这可能永远不会发生。例如,如果您将 4 除以 5,则减法将产生负溢出,并且累加器将不会为零(实际上它没有由语言定义,然后它会有什么值)。您应该使用BRP
. 构建循环条件逻辑,而不是在那里使用 Q
的初始化取自99号邮箱,但前提是你的程序不占用99号邮箱。这个是对的,不过最好给一个DAT 0
打个标签.- 没问题,但是不需要第三条指令 (
LDA NUM1
),因为累加器已经有了那个值。
BRZ
你要实现的算法有点啰嗦。在您从第一个数字中减去第二个数字并且没有更多的减法是可能的之后,您将已经有了余数(如果您做对了)。
您的算法还应该以不同方式处理 0 除数:在这种情况下,可能会输出一些预定义的值以指示商未定义,例如 999。
这里是你如何编码的。这是一个可运行的片段,其中包含一些您可以改编的示例输入:
#input: 19 5
LDA zero # initialise
STA quotient
INP
STA remainder
INP
STA divisor
BRZ error # division by 0 is undefined
loop LDA remainder
SUB divisor
BRP continue
end LDA quotient # output the results
OUT
LDA remainder
OUT
HLT
continue STA remainder
LDA quotient
ADD one
STA quotient
BRA loop
error LDA big # output 999 twice to indicate error
OUT
OUT
HLT
remainder DAT
divisor DAT
quotient DAT
zero DAT 0
one DAT 1
big DAT 999
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.816/lmc.js"></script>