如果我在单元格D1中有一个数字,并希望它始终为偶数,该如何确保它永远不是奇数?
我知道这与AND指令有关。但是当我尝试过后,它总是会减去1。所以它会将奇数转换为偶数,偶数转换为奇数。
基本上,我应该如何执行如果n是奇数,则减去1
的操作?
如果我在单元格D1中有一个数字,并希望它始终为偶数,该如何确保它永远不是奇数?
我知道这与AND指令有关。但是当我尝试过后,它总是会减去1。所以它会将奇数转换为偶数,偶数转换为奇数。
基本上,我应该如何执行如果n是奇数,则减去1
的操作?
and
命令将您的数字与-2
进行操作。
在二进制补码表示法中,-2是一个所有位都设置为1除了最低位的数(11111...110),因此,用作掩码时,它总是只清除您数字的最低有效位。这迫使它成为偶数(即使对于负数也能正常工作)。
至于标题中的“反之亦然”,要执行相反操作(即将每个偶数强制转换为下一个奇数),只需使用or
命令并加上1
。这将使最低有效位设置为1,从而获得所需的效果。
1
结尾,偶数以0
结尾。你真正想要的是使最后一位二进制数字变成0
,无论它最初是什么。(这将从奇数中减去1,而让偶数保持不变。)1111...1110
进行按位与运算,其中所有二进制数字都是1
,除了最后一位是0
。你可以通过对0000...0001
进行按位取反来构造它,这当然只是1
。n
,你需要计算n & (~1)
。只需要清除底部一位,所以虽然其他人使用了长字指令,但使用AND的字节形式也没有问题。
AND.B #0xFE, D1 ; make even
OR.B #0x01, D1 ; make odd
XOR.B #0x01, D1 ; toggle even/odd
BCLR #0,D1 ; make even
BSET #0,D1 ; make odd
BCHG #0,D1 ; toggle even/odd
68000 CPU实际上有单独的位设置和位清除命令。在像你这样的情况下,明确地清除操作数的第0位可能会更简单和更清晰,而不需要回到布尔逻辑:
bclr.l #0,d0
替代
and.l $fffffffe,d0
EvenNumber = (D1 & 0xFFFE);
and
并不总是减去1(例如(12 and 254) = 12
…只有像(13 and 254) = 12
这样的情况可能看起来像减1)。 - Ped7g