我需要编写一个LMC程序来计算给定值a、b、c和x的a+bx+cx²的值。如果结果超过999,则需要输出999;如果小于999,则输出结果。
a+bx+x²部分(没有c系数)已经由@trincot在这个答案中完成:
INP
STA a
INP
STA b
INP
STA x
STA x2
LDA z # "inverse" ans
SUB a # do this first
loop STA ans
LDA x
BRZ output
SUB one
STA x
LDA ans
SUB x2 # subtract both x...
BRP continue
BRA overflow
continue SUB b # ... and b
BRP loop
overflow LDA zero # prepare for outputing 999 (overflow)
STA ans
output LDA z
SUB ans # 999 - (999 - (a + bx + x^2))
OUT
HLT
a DAT 0
b DAT 0
x DAT 0
x2 DAT 0
z DAT 999
ans DAT 0
zero DAT 0
one DAT 1
但不知道如何修改此代码,以便添加c次x²
要最小化所需的逻辑,可以按如下方式计算−−²:
−(−)
这有一个递归模式,因此一旦得到内部表达式的结果,用于内部表达式−的逻辑与用于外部表达式的逻辑相同:−。如果我们交换变量中的值,并且,我们可以执行以下序列:
:=−
:=
:=−
然后将是最终答案。显然,我们可以将以下内容放入一个执行两次的循环中:
:=−
:=
第二件需要考虑的事情是代码已经做了什么。我引用了我的答案中的代码来源:
确实很难检测到溢出(超过999),因为通常LMC累加器不能存储更大的值,并且当这种溢出发生时(在规范中)没有定义累加器的值,也没有指定";否定的";标志将被设置。因此,我们真的没有什么可以用来检测这种溢出,这在所有LMC模拟器上都是兼容的。
诀窍是将表达式计算为999−(−−²),并检测负溢出(低于0),为此我们有
BRP
指令。
所以在这里我们将执行";反转";在循环开始时,继续减法(而不是加法),最后(如果没有出现负溢出)再次反转结果。
这是这个想法的一个实现——你可以在这里运行它:
#input: 2 5 2 3
INP
STA a
INP
STA b
INP
STA c
INP
STA x
LDA one
repeat STA counter # Execute twice: b + c*x => c, and a => b
LDA max
SUB b # invert b
BRA step
loop STA c
LDA inv
SUB x
BRP step
LDA max # indicate overflow
OUT
HLT
step STA inv
LDA c
SUB one
BRP loop
LDA max
SUB inv # re-invert and store in c
STA c
LDA a
STA b # The second time b takes the role of a
LDA counter
SUB one
BRP repeat
LDA c
OUT
HLT
a DAT
b DAT
c DAT
x DAT
counter DAT
inv DAT
zero DAT 0
one DAT 1
max DAT 999
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.816/lmc.js"></script>