如何在LMC中将cx^2添加到a+bx,溢出输出为999



我需要编写一个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次

要最小化所需的逻辑,可以按如下方式计算−−²:

−(−)

这有一个递归模式,因此一旦得到内部表达式的结果,用于内部表达式−的逻辑与用于外部表达式的逻辑相同:−。如果我们交换变量中的值,并且,我们可以执行以下序列:

:=−
:=
:=−

然后将是最终答案。显然,我们可以将以下内容放入一个执行两次的循环中:

:=−
:=

第二件需要考虑的事情是代码已经做了什么。我引用了我的答案中的代码来源:

确实很难检测到溢出(超过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>

最新更新