4

Basically if I had a number in D1, and wanted it to ALWAYS be even, how would I make sure it is never odd?

I know it has something to do with the AND instruction. But when I tried that, it would always subtract 1. So it would turn odd numbers even and even numbers odd.

How can I basically do if n is odd, sub 1

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    *So it would turn odd numbers even and even numbers odd*: AND can't set bits, only clear them or leave them set, so it can't make an even number odd. So your attempt with AND must have had a bug that made it do something else. (XOR with 1 would flip the low bit, flipping between odd and even. So would ADD 1, but that would carry into high bits.) Anyway, hopefully with these answers + the debugger built in to easy68k you can sort out what you actually did. – Peter Cordes May 03 '18 at 07:15
  • *"... AND instruction. But when I tried that, it would always subtract 1."* - that's literally impossible. If you really believe into this, you should try to produce [MCVE] of that, but you should figure out yourself the `and` does not **always** subtract 1 (for example `(12 and 254) = 12` ... only cases like `(13 and 254) = 12` may look like subtraction of 1). – Ped7g May 03 '18 at 14:20

5 Answers5

5

and your number with -2.

In 2's complement representation -2 is a number with all bits set to one except the lowest one (11111...110), so, used as a mask, it always kills just the low bit of your number. This forces it to be even (it works correctly even for negative numbers).


As for the "viceversa" in the title: to do the opposite (=force every even number to the next odd), just or with 1. This sets the low bit to be 1, which obtains the required effect.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
4

Odd numbers end with 1 in binary, and even numbers end with 0 in binary. What you really want is to make the last binary digit be 0, regardless of what it started as. (That'll subtract 1 from odd numbers, and leave even numbers unchanged.)

The way to do this is to AND with 1111...1110, where all binary digits are 1 except the last digit, which is 0. You can construct this by doing a bitwise negation on 0000...0001, which of course is just 1.

So if your number is n, you want to compute n & (~1).

k_ssb
  • 6,024
  • 23
  • 47
2

The 68000 CPU actually has separate bit set and bit clear commands. In cases like yours, it might be simpler and clearer to explicitly clear bit 0 of the operand without reverting to boolean logic:

bclr.l #0,d0

instead of

and.l $fffffffe,d0
tofro
  • 5,640
  • 14
  • 31
2

You only need to clear the bottom bit, so whilst others have used long word instructions, there's nothing wrong with using the byte form of AND

AND.B #0xFE, D1   ; make even
OR.B  #0x01, D1   ; make odd
XOR.B #0x01, D1   ; toggle even/odd

No matter what the size of the value in D1 (byte, word or longword), you've still cleared the bottom bit and left all the other bits in the register unchanged

Alternatively

BCLR #0,D1  ; make even
BSET #0,D1  ; make odd
BCHG #0,D1  ; toggle even/odd 
vogomatix
  • 4,856
  • 2
  • 23
  • 46
1

For a 16 Bit Number do this:

EvenNumber = (D1 & 0xFFFE);
Mike
  • 4,041
  • 6
  • 20
  • 37