我正在嘗試撰寫一個 LMC 程式,它接受兩個整數輸入,將它們相除,然后產生商和余數。首先,我將問題分解為 4 個階段:
1. 將 num1 除以 num2 得到商 q。
2.q和num2相乘得到精確的相乘數,存入num2。
3.從num1中減去num2,并將答案存盤在rem中。
4.輸出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 模擬器中運行代碼時,它不會產生結果,而是無限期地繼續計算。我怎樣才能讓它作業?有一個更好的方法嗎?任何幫助是極大的贊賞。
uj5u.com熱心網友回復:
有一個更好的方法嗎?
你的方法是合乎邏輯的,但可能有點矯枉過正。單獨做除法,當你不能再從被除數中減去除數時停止,就會同時產生商和余數。
例如,如果你想將 13 除以 4,然后從 13 中減去 4 得到 9,然后從 9 中減去 4 得到 5,然后從 5 中減去 4 得到 1,現在我們停止,因為 4 大于 1(我們不能減去沒有消極)。商是我們能夠減去 4(3 次)的次數,余數是停止后剩下的,這里是 1。
我怎樣才能讓它作業?
至于為什么您的代碼執行無限回圈,很可能您只是在尋找精確的除法,使用BRZ. 您應該考慮BRP改為使用,這將允許非零余數。您應該在 LMC 除錯器中單步執行,看看為什么它不會在您想要的時候停止。
uj5u.com熱心網友回復:
你的程式有幾個問題:
OUT不接受論證。它不應該OUT Q,而只是OUT。一個好的 LMC 模擬器應該抱怨這個。LOOP被定義為一個標簽兩次。這是模棱兩可的。一個好的 LMC 模擬器應該抱怨這個。- 下面的代碼
BRA LOOP無法訪問,直到END. 這是死代碼。 - 回圈只能在
NUM1變為零時退出,但這可能永遠不會發生。例如,如果您將 4 除以 5,那么減法將產生負溢位,并且累加器不會為零(實際上,它并沒有由語言定義然后具有的值)。而不是使用的BRZ有,你應該使用構建回圈條件邏輯BRP。 - 的初始化
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/[email protected]/lmc.js"></script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/369166.html
