按位运算异或掩码

bitwise operation xor mask

如果这看起来像一个愚蠢的问题,我很抱歉,我只是无法理解位和按位运算赋值

我有两个整数,一个是掩码,另一个是任意整数,我应该用掩码的 16 个最高有效位对整数进行异或运算,但我不确定前 16 位是有效位还是最后 16 个,如果我的操作是正确的,因为我不知道如何验证它 我试过这个

int main(){
    uint32_t mask = 3405705229;
    uint16_t arbitrary = 0xABCD;

    arbitrary^=mask&16;
    printf("%X\n",arbitrary);
}

我假设 mask&16 只会给我掩码的前 16 位 但是当我打印时我仍然得到 ABCD 所以那是不对的.. 我也试过 arbitrary^=(mask>>16)&16; 但那也没有做任何事

对于无符号的 8 位值,您可能有:

Bit number:    7   6   5   4   3   2   1   0
Bit value:     1   0   0   0   1   1   0   1   = 141 = 0x8D

4 个最高有效位 (MSB) 是位 7-4; 4 个最低有效位 (LSB) 是位 3-0。

您将使用以下方法从 uint8_t x8 = 141; 中提取 4 个最高有效位:

uint8_t y = (x >> 4) & 0xF

输出将是 y 等于 8 或 0x08

当然,您可以扩展它以容纳更多的位数。

请注意,MSB 和 LSB 通常用于 {Most|Least} Significant Bytes 而不是 bits — 但这仍然适用于与 8 位字节块中的逻辑值类似的方式。正如评论中的 paulsm4 一样,这适用于逻辑值。 CPU 有两种主要类型:big-endian(SPARC、较旧的 PowerPC、Motorola 等)和 little-endian(英特尔和许多其他芯片,包括现代 PowerPC 至少作为一种选择)。不同之处在于多字节(整数)值的字节存储顺序:

对于值为0x12345678的4字节无符号整数,两种类型以相反的顺序存储数据:

地址 0x1000 0x1001 0x1002 0x1003 大端 0x12 0x34 0x56 0x78 小端 0x78 0x56 0x34 0x12

Big-Endian MSB ... ... LSB 小端 LSB ... ... MSB

如今,小端法更为普遍。然而,许多网络协议和其他系统要求大端。大多数时候,您不必担心。有时,您会这样做——知道什么时候做、什么时候不做很重要。单台机器上的数据不在其他地方共享,通常不需要您担心字节顺序。您不必担心(单字节)字符串中数据的字节顺序。

在二进制数中,最左边的位称为最高有效位(msb),最右边的位称为最低有效位(lsb)。如果有人说要用 16 个最高有效位进行屏蔽,那么您应该尝试从左到右获取这 16 个位。

你可以借助左移运算符得到最高16位。

左移运算符将数字向左移动并用零填充最高有效位(负数不应使用左移运算符)。

所以下一行就可以完成这项工作。

arbitrary^=(mask>>16);

最高有效位是最高位(从左开始)。由于掩码是 32 位,您只需移动左 16 位以覆盖右 16 位。左边的 space 将用零填充。 然后你可以将这个掩码与你的 16 位数字一起使用。

int main(){
    uint32_t mask = 3405705229;
    uint16_t arbitrary = 0xABCD;

    arbitrary^ = (mask>>16);
    printf("%X\n",arbitrary);
}

输出:6133

顺便说一句,掩码值是个笑话吧?在十六进制中,它的值为 CAFEF00D。 (你也应该试试 uint16_t arbitrary = 0x1453;)

I'm not exactly sure if significant is the first 16 or the last 16 and if my operation is even correct since I don't know how to verify it I tried this

一种简单的验证方法是将您的数据更改为一些易于猜测的数字。

只需尝试使用 mask == 1,这将使偶数成为下一个奇数或正奇数成为前一个偶数。