How create an Little Mans Computer (LMC) code that will get a number. Display 1 if the number is odd, display 0 if the number is even

后端 未结 3 1529
夕颜
夕颜 2021-01-29 15:19

I need help in my study\'s where it can display 1 if the number is even and 0 if the number is odd. for example if the input is 99 it will display the output 1 which means odd.

相关标签:
3条回答
  • 2021-01-29 16:02

    wow, that thing does not have AND?
    LMC link 1
    LMC wiki

    Hm, ok, let me think for a while, without AND this is tricky. On algorithm level it looks like you have to loop trough decreasing the input number by one till zero, and do result = 1 - result each iteration. At the end you will have either one or zero in result (depending on the initial value of result (0 or 1, you decide), and oddness of the input number).

    Now you have to write this for LMC, I'm not going to learn it on the fly now. If you are completely lost, read the wiki page, find out some emulator, run in it some example code, and study it instruction by instruction, what it does, try to figure out why. Then try few more examples and see how they work, then come back to the algorithm I wrote, and try to write it on your own.

    (if still lost, you should have a specific question to each of those points, which will be much easier to answer, some of them very suitable for SO .. your original question looks a bit too broad and lacking, I sort of wonder you haven't been already downvoted and put "on hold").

    edit (for fun):
    That r=r-1 is a way how to flip between 0 and 1 when you have only subtraction. Usually CPUs have also xor and not instructions making the operation more straightforward (from bitwise assembler programmer point of view), but I tend to use the r=r-1 in Java to make it easier for reading for my colleagues, who keep forgetting what is xor and then they are puzzled by r^=1;

    0 讨论(0)
  • 2021-01-29 16:03

    It is possible to tell odd and even numbers apart by doing a division through repeated subtractions.
    In general, a number is even if it is divisible by two, or in more pragmatic terms if the rest of the division by two is zero1.

    To divide b by a we can simply subtract a from b and repeat until the freshly updated b is less than a.
    The number of times we looped is the number b/a, the value left in b is the reminder b mod a.
    We are interested in the latter, so we won't count the number of iterations.

    Input b
    While b >= 2 Do
       b = b - 2
    End While
    
    If b == 0 Then
       Output 1;
    Else
       Output 0;
    End If
    

    Unfortunately, LMC doesn't have a compare with immediate instruction.
    This is not a problem however as we can rewrite b >= 2 as b - 2 >= 0 which is something closer to what LMC can do.
    But b - 2 is the same computation done in the loop, so we can reuse that entirely

    Input b
    Do
       b = b - 2
    Loop While b >= 0
    b = b + 2
    
    Output b
    

    The b = b + 2 is needed because on exit from the loop b is negative, it is either -1 (if the number was odd) or -2 (if the number was even). That's why I added the equal sign to the loop condition.
    By adding 2 we can then directly output b.


    The algorithm above compute the complement of your problem, it outputs 0 for even numbers and 1 for odd ones.
    I silently added this "twist" so that a dumb copy-paste will harm you.

    Since it is a homework, I leave the task of inverting the output to your self.

    The code is below, hidden.
    Please, note that this code doesn't solve the original exercise, using it as it will get you a zero.

    INP                       ;ACC = Number from user
    sub2_loop
    
      SUB two                 ;ACC = ACC - 2
    
    BRP sub2_loop             ;If ACC >= 0, keep subtracting 2
    
     ;ACC < 0, since we were subtracting 2 ACC can only be -1 or -2
    
     ADD two                  ;Set ACC = 1 or 0
    
    end
     OUT                      ;Show ACC
     HLT
    
     two DAT 2


    1 Usually programmers take advantage of the base two properties (namely that 20 is the only odd power of two) but that requires an AND or a SHIFT operation to extract to least binary digit.
    LMC doesn't have either and doesn't even natively works with binary numbers, so we need to emulate a division.

    0 讨论(0)
  • 2021-01-29 16:07

    Margaret's answer expects the accumulator to have a determined value when the negative flag is set by a previous subtraction of 2. Or at least that adding 2 to that would bring the accumulator back in its previous state.

    This may be true in some implementations, but there is no guarantee. In theory the LMC only deals with non-negative numbers, and the only notion of negative is in the "negative" flag. Wikipedia warns that the accumulator's value is undefined after a subtraction leads to overflow on the negative end.

    There is for instance this implementation of an LMC where the accumulator will be set to -1 whatever the magnitude of the overflow is, and so the distinction between odd and even is lost at that moment. Many will consider this a very odd implementation, but it is compliant with the LMC specification.

    Here is a version that does not make assumptions beyond the LMC specification:

    #input: 9
           INP
      loop STA result
           SUB two
           BRP loop
           LDA result ; restore value from before subtraction
           OUT
           HLT
       two DAT 2
    result DAT
      
    <script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.7/lmc.js"></script>

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