LMC: base conversion from decimal to base 9 included

后端 未结 1 656
醉酒成梦
醉酒成梦 2021-01-22 03:55

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

相关标签:
1条回答
  • 2021-01-22 04:40

    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.

    0 讨论(0)
提交回复
热议问题