我正在尝试解决这个代码挑战:
编写一个 LMC 程序来计算用户提供的数字的总和。在停止程序之前将总和显示为输出。如果用户提供的输入值少于或等于十个,则仅对偶数求和。奇数将被忽略。如果用户提供了十个以上的值,则仅对第十个输入之后的所有奇数求和。现有的偶数总和应保留。如果用户在任何时候输入零,则会显示总和。
例如:
输入值:3, 3, 4, 0
结果:4输入值:2、3、7、0
结果:2输入值:1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,0 结果:
43
在这里,您可以看到我的程序使用第一个示例的输入运行,它显示输出为 0(而不是预期的 4):
我不确定代码有什么问题会给出错误的输出。我的错误在哪里?
代码:
start
INP
STA input
BRZ halt
LDA inputCounter
SUB ten
BRP afterTen
// Input <= 10
LDA input
STA isEven
SUB one
BRP oddNumber
LDA isEven
ADD one
STA isEven
SUB two
BRZ evenNumber
oddNumber LDA inputCounter
ADD one
STA inputCounter
BRA start
evenNumber LDA input
ADD evenSum
STA evenSum
LDA inputCounter
ADD one
STA inputCounter
BRA start
// Input > 10
afterTen LDA input
STA isEven
SUB one
BRP evenAfterTen
LDA isEven
ADD one
STA isEven
SUB two
BRZ oddAfterTen
evenAfterTen LDA inputCounter
ADD one
STA inputCounter
BRA start
oddAfterTen LDA input
ADD oddSum
STA oddSum
LDA inputCounter
ADD one
STA inputCounter
BRA start
// Display sum
halt LDA evenSum
ADD oddSum
OUT
HLT
// Variables
evenSum DAT 0
oddSum DAT 0
inputCounter DAT 0
isEven DAT 0
input DAT 0
// Constants
one DAT 1
two DAT 2
ten DAT 10
问题出在检查数字是否为偶数的部分。该代码首先会减1,如果该指令没有导致负数溢出,则得出该数字是奇数的结论!这显然不(总是)正确。例如,如果您从 2 开始,那么它会错误地得出奇数的结论。
要测试一个数字是否为奇数,您需要(在 LMC 的限制下)一个循环,在其中重复减去数字 2,直到达到零或出现负溢出。
由于您的代码后半部分有类似的代码,因此该问题也在那里重复出现。
这是一个更正:
评论
不需要单独的
evenSum
和oddSum
。您只需添加到相同的sum
.有一些代码重复:两段代码执行奇/偶测试。您可以通过
isEven
在处理前十个之后的输入时添加 1 来避免这种重复,然后您可以使用相同的代码来执行奇/偶测试,因为通过添加 1 可以反转结果。由于小人计算机具有重置功能,该功能会重新启动程序而不将邮箱内容重置为其原始值(包括
DAT
),因此您将得到不一致的输出,特别是evenSum
和oddSum
“变量”将不会被重置。为了避免这种情况,请在程序一开始添加指令以将总和设置为零。以下是经过这些改进的代码: