LMC: base conversion from decimal to base 9 included

余生长醉 提交于 2019-12-02 05:42:14

问题


I am trying to create an LMC assemble code that will allow a user to put two inputs: a decimal number and a base that the number should be converted to. The code should be able to convert any decimal number to any base between 2 and 9 included.

I am aware that the division is not available on LMC: I can use subtractions. Lets say, from 12 decimal to base 3, I am able to get 12-3-3-3-3= 4, but how can I make the code understand that the rest of the division 12/3= 4 and rest of the division is 0 and 4-3=1 but 4/3=1,... so the rest of the division is 1-3=-2 and 1/3 is 0,33... so the rest is 1. Now reading it in opposite sense, 12 decimal to base 2 is 110.

But again, even the 1-3= -2: how can I make it understand that the rest is 1?

Also, how can I make the code understand it's within which base? Do I create a long code first for detecting the base? And let's say it's going to BRA depending which base it is, then I'm not even sure if it's the same algorithm for all the bases...

I am a bit confused here, but even if someone can help me understand how to make the code for getting the remainder of the division, that's gonna help me a lot.


回答1:


I'll assume that the output should be a series of single-digit numbers representing the given decimal number in the given base notation.

You could use a data-based approach: store all relevant powers of 2, 3, 4, ... and 9 in memory (mailboxes). We only need powers that are not greater than 999, so this list is limited:

  • Base 2: 1 2 4 8 16 32 64 128 256 512
  • Base 3: 1 3 9 27 81 243 729
  • Base 4: 1 4 16 64 256
  • Base 5: 1 5 25 125 625
  • Base 6: 1 6 36 216
  • Base 7: 1 7 49 343
  • Base 8: 1 8 64 512
  • Base 9: 1 9 81 729

This also has the advantage that you don't have to perform that many subtractions. Imagine the difference when the input is 999 and base 2. If you have the powers of 2 already available (up to 512), you'll only do about 9 subtractions, while if you try to do it with only 2, you'll do hundreds of subtractions...

So, given these powers, use a "pointer" in that list (through self modifying code) that will first find the range of powers that belong to the given base, and then will take it from there to perform repeated subtractions of a power (greatest first) from the original number to determine each output digit.

With some care you can avoid that zeroes are output as long as no one has been output.

Here is how that could be coded:

#input: 12 2
         INP          // number
         STA DECIMAL
         INP          // base
         SUB ONE
         STA BASE
LOOPBASE LDA BASE    // count down to find powers of base
         SUB ONE
         STA BASE
         BRZ DIVIDE

 LOOPPOW LDA CODE1    // take next power
         ADD ONE
         STA CODE1    // self-modifying
         LDA ONE      // is it 1?
   CODE1 SUB POWER    
         BRZ LOOPBASE // yes...
         BRA LOOPPOW  // no... 
        
  DIVIDE LDA CODE1
         ADD ONE
         STA CODE2
         BRA ENTRY
        
    LOOP STA DECIMAL
         LDA DIGIT     
         ADD ONE
         STA DIGIT     
   ENTRY LDA DECIMAL
   CODE2 SUB POWER     
         BRP LOOP
         LDA FIRST   // do not output prepadded 0
         BRZ OUTPUT  // not the first digit
         LDA DIGIT
         BRZ SKIP
  OUTPUT LDA DIGIT
         OUT
         SUB DIGIT
         STA FIRST   // no longer first digit
    SKIP STA DIGIT
         LDA CODE2
         ADD ONE
         STA CODE2   // self-modifying
         STA CODE3   // self-modifying
         LDA ONE     // is power 1?
   CODE3 SUB POWER
         BRP FINISH  // yes
         BRA ENTRY
        
  FINISH LDA DECIMAL
         OUT
         HLT
         
 DECIMAL DAT
 BASE    DAT
 DIGIT   DAT
 FIRST   DAT 1

   POWER DAT    
         DAT 512 // powers of 2
         DAT 256
         DAT 128
         DAT 64
         DAT 32
         DAT 16
         DAT 8
         DAT 4
     TWO DAT 2
     ONE DAT 1
         DAT 729 // powers of 3
         DAT 243
         DAT 81
         DAT 27
         DAT 9
         DAT 3
         DAT 1
         DAT 256 // powers of 4
         DAT 64
         DAT 16
         DAT 4
         DAT 1
         DAT 625 // powers of 5
         DAT 125
         DAT 25
         DAT 5
         DAT 1
         DAT 216 // powers of 6
         DAT 36
         DAT 6
         DAT 1
         DAT 343 // powers of 7
         DAT 49
         DAT 7
         DAT 1
         DAT 512 // powers of 8
         DAT 64
         DAT 8
         DAT 1
         DAT 729 // powers of 9
         DAT 81
         DAT 9
         DAT 1  

<script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.7/lmc.js"></script>

This uses almost all available mailboxes. Probably some optimisation in space use is still possible.



来源:https://stackoverflow.com/questions/55409767/lmc-base-conversion-from-decimal-to-base-9-included

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!