1

I'm working on a project but I'm stuck. I'm trying to write a snippet of code that checks if the given number is even by subtracting it by 2 (the given number cannot be more than 6). If it's even it prints a 0, if it's odd it prints a 1.

    int count=input.nextInt()
    int parity=0

    while (count>0)
        count=count-2;
        if (count<0) {
            parity=parity+1;
            System.out.print(parity);
        }
        else if (count==0) {
            System.out.println(parity);
        }

^^ That's my java code that I've tried translating into MARIE language but nothing works.

I'd post my MARIE code but I feel that it's too confusing :/

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Grace D
  • 15
  • 5
  • Normally you *should* post your asm code, and mark it with comments to say which parts you know won't work, and with comments to describe how the parts are supposed to work (including for the parts you think are correct.) We can't give you a very specific answer if you don't show your attempt. Although in this case it's easy to see why starting from that messy Java would be hard! So many conditions *inside* the loop. – Peter Cordes Mar 13 '18 at 06:26
  • There are far more efficient way for determining if a number is even... For example, test to see if the lowest order bit is zero. – David Hoelzer Mar 13 '18 at 11:29

1 Answers1

1

You only need to check the low bit for 0 / non-zero. Normal architectures have an AND instruction that would make that simple, but MARIE only has add/sub (and compare for greater or less-than).

But yes, your loop will work, taking O(n) iterations for a number n. It would be a lot easier to implement in asm if you wrote it as a do{}while() loop, like

n = input;
do {
    n-=2;      // sub
}while(n>=0);  // skipcond
// n==0 or -1 for even or odd

You can do it in O(log(n)) operations by using add as a left shift: AC+AC is the same thing as AC << 1. Do this 15 times to shift the low bit to the top, and the other bits out. (The accumulator, AC, is 16 bits wide).

This is unfortunately really inconvenient on MARIE, because ADD only works with a memory source operand, not with AC. So you'd have to store AC somewhere so you can use it as a memory source operand for ADD.

(This is definitely not worth it when you know your input is in the range 0..6. In that case, it only takes at most 3 iterations of the n-=2 loop to get the result, vs. always 15 for this. But with unrestricted inputs, the n-=2 version could need 32768 iterations! Or 16384 if we limit this to positive signed integers; the n-=2 version doesn't even work for negative integers)

So for example:

/ Assuming input in AC

Store tmp
Add   tmp

Store tmp
Add   tmp
/ repeat this 13 more times, for a total of 15 ADDs
/ inconvenient to make a loop because Marie only has 1 register
/ but would be smaller for this many shifts

/ AC = input << 15

/ AC is non-zero for odd, zero for even.  You could just store that directly if you want.

/ If you want to branch on it here, or in some code that reloads that 0 / non-zero result
SkipCond  400     / jump over next insn if AC==0
jump     odd_input     / or this can be a store instruction
/ else fall through when input was even: input&1 == 0


tmp, dec 0

A loop would make sense, especially if you unrolled it by 2 or something. If AC was only 8 bits, fully unrolling would only take 7 STORE/ADD instructions, but 15 is a bit much.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847