基于Little Man Computer的十进制转任意进制程序开发问题
解决Little Man Computer(LMC)进制转换的循环与输出问题
我来帮你搞定这个LMC进制转换的问题!你的代码目前遇到两个关键问题:一是减法循环没处理负数导致无限循环,二是你现在计算的是商而非余数,而且就算拿到余数也没法按正确顺序输出(进制转换的余数是从低位到高位生成的,直接输出会反过来)。咱一步步来改:
问题拆解
- 负数无限循环:你的
LOOP里先减base,再判断是否为0。但当number小于base时,减法后会得到负数,这时候BRZ END不会触发,程序会一直重复减base,累加器一直是负数,陷入死循环。 - 错误计算商而非余数:你现在用
ANS累加的是减base的次数(也就是商),但我们需要的是每次number除以base后的余数,这才是进制转换的每一位数字。 - 输出顺序颠倒:进制转换时,第一次得到的余数是结果的最低位,最后一次得到的是最高位,直接输出会反过来(比如12转二进制,你会先拿到0、0、1、1,但正确输出应该是1100)。
解决思路
- 用减法模拟模运算:每次循环中,重复减base直到
number小于base,剩下的就是余数;减的次数就是商,作为下一次循环的number。 - 用内存栈存储余数:LMC没有数组,但可以用连续的内存地址依次存储余数,记录存储的个数,最后从最后一个余数开始反向输出。
- 处理负数判断:每次减base前先判断
number是否大于等于base,避免出现负数。
修正后的LMC代码
INP // 输入十进制数 STA NUM // 存储到NUM INP // 输入目标进制 STA BASE // 存储到BASE LDA ZERO STA COUNT // 初始化余数计数为0 LOOP: LDA NUM BRZ PRINT // 如果NUM为0,开始输出余数 LDA NUM SUB BASE BRP UPDATE_NUM // 如果减完后非负,更新NUM // 减完后为负,说明当前NUM就是余数 LDA NUM STA RES, COUNT // 把余数存入RES的对应位置(COUNT作为偏移) LDA COUNT ADD ONE STA COUNT // 计数+1 LDA ZERO STA NUM // NUM设为0,准备退出循环 BRA LOOP UPDATE_NUM: STA NUM // 更新NUM为减base后的值 BRA LOOP // 继续循环减base PRINT: // 先检查是否有余数(比如输入0的情况) LDA COUNT BRZ PRINT_ZERO // 从最后一个余数开始反向输出 LDA COUNT SUB ONE STA COUNT // 计数减1,指向最后一个余数 LDA RES, COUNT // 取出当前余数 OUT // 输出 LDA COUNT BRNZ PRINT // 如果计数还没到0,继续输出 BRA END PRINT_ZERO: LDA ZERO OUT // 输入0时输出0 END: HLT NUM DAT // 存储待转换的数 BASE DAT // 存储目标进制 COUNT DAT // 余数的个数 RES DAT 0 // 存储余数的起始地址(后续用偏移访问) ONE DAT 1 ZERO DAT 0
测试12转二进制的流程
- 输入12和2,
NUM=12,BASE=2,COUNT=0 - 循环处理:
- 12反复减2直到为0,得到余数0,存入
RES[0],COUNT变为1,NUM更新为6 - 6反复减2直到为0,得到余数0,存入
RES[1],COUNT变为2,NUM更新为3 - 3减2后为1(非负),继续减2得到-1,此时余数为1,存入
RES[2],COUNT变为3,NUM更新为1 - 1减2后为-1,余数为1,存入
RES[3],COUNT变为4,NUM设为0
- 12反复减2直到为0,得到余数0,存入
- 输出阶段:从COUNT=3开始,依次取出
RES[3]=1、RES[2]=1、RES[1]=0、RES[0]=0输出,最终得到正确的二进制结果1100
这样就解决了你的无限循环问题,同时正确输出转换后的进制数啦!
内容的提问来源于stack exchange,提问作者soso xoxo
相关产品推荐
相关产品推荐

