Reputation: 13
Normally you would just use modulus to determine this but since that is not an option I tried to use a repeated subtraction loop and utilized skipcond400 to determine if the value was equal to 0. This was perfectly fine if every time i were to input a number it was even. The problem im having is if the number is odd, that condition would never be met resulting in an infinite loop. I could use skipcond000 as an alternative but it would not be able to tell me if a number is even because odd numbers would never equal 0 as they cannot be divided exactly into pairs. Im stuck on how to even determine this because my ultimate goal is to use this to add all the even numbers leading up to a certain value. In order to do this though I would first need to determine whether user input is even or odd so that way I can have a different set of instructions to do. So far I had something like this in mind but i legitimately have no idea where to go from here. Am i approaching this totally wrong?
ORG 100
Input
Store y //store input in a variable thats not messed with
Load y
Store x //store a duplicate of the input so i can mess with it
loop, Load x // loop that does repeated subtraction
Subt two
Store x
Skipcond 400
Skipcond 000
Jump loop
x, DEC 0
counter, DEC 0
two, DEC 2
Upvotes: 1
Views: 1176
Reputation: 350252
Continuously subtracting 2 is a possibility, but if the input is large, this can take a long time to run.
You could improve on this by making use of the fact that MARIE numbers are signed 16-bit integers and we have a way to know the value of the signbit (using SkipCond
). On the other hand, it is the least significant bit that determines whether a number is even or odd. If now we shift that bit to become the signbit, then we are essentially done.
To shift the bits of a number one position to the left, we just need to multiply the number by 2 (add it to itself). To make the least significant bit the sign bit, we should shift the number with 15 positions, i.e. we should add the number to itself and do that 15 times.
Here is an implementation of this idea:
Input
JnS isOdd / Will set AC to 0 or 1, to indicate "even" (0) or "odd" (1)
Output
Halt
/ -------- Subroutine isOdd(AC) --------------------------------------- \
isOdd, Hex 0 / Space for the return address
Store ioNum / Save the number to be shifted
Load ioOne / Initialise loop variable with a stop-bit
Store ioFollow
ioRepeat, Add ioFollow / Shift loop bit left
Store ioFollow
Load ioNum
Add ioNum / Shift input left
Store ioNum
SkipCond 400 / No more 1-bits in number?
Jump ioContinue / No, still 1-bits present: continue
JumpI isOdd / Yes: return that number is even (AC=0)
ioContinue, Load ioFollow / Check whether done
SkipCond 000 / Loop variable's bit is signbit?
Jump ioRepeat / No: make next iteration
Load ioOne / Yes: return that number is odd (AC=1)
JumpI isOdd
/ Variables for isOdd
ioNum, Dec 0
ioFollow, Dec 0
/ Constants for isOdd
ioOne, Dec 1
You can assemble and run the above code on MARIE.js.org.
Upvotes: 0
Reputation: 61875
The original code is using a valid approach to solving the task. The pseudo-code below is constructed to show how one might use the limited skip-branching in MARIE. Using label names a comments can help to illustrate expectations at various statements.
load X into accumulator
detect_even:
substract 2 from accumulator
skip if accumulator is positive
goto zero_or_neg
# 'accumulator is positive'
goto detect_even
zero_or_neg:
# accumulator is -1 or 0
skip if accumulator is zero
goto not_even
# 'accumulator is zero'
# no op, goto even, or omitted instruction
even:
# here X is even as accumulator is 0
# use X, perhaps add to running total?
not_even:
Note that the accumulator is reused for the primary detection loop, much as though X - Y - Y - Y - ..
. YMMV with negative numbers.
Upvotes: 0
Reputation: 26646
There's no AND
instruction on MARIE, which on other machines would be used to easily isolate the lowest bit.
There are several techniques you could use. Combining Skipcond
is super confusing but can be made to work. However, you should be aware that Skipcond
actually cannot do all the conditions we would like it to do so, we do end up resorting to clever sequences like what you're suggesting.
Your sequence will continue when the current value is zero, which I think is an error.
I believe what you want to do is continue the modulus loop only if the value is > 0. See this answer (table near the end) to identify sequences for that: https://stackoverflow.com/a/66725608/471129.
You should also be able to use multiple Skipcond
s in a sequence, but to be repetitive, super confusing though should be workable.
An alternative is to shift the bit of interest. Each time you double a number, which can be done by adding to itself, that will perform a left shift. 15 of those will move the LSB (which tells us if the number is even/odd) to the MSB position, which can be tested using Skipcond
.
Upvotes: 0