关于 c:Swapping 2 Bytes of Integer | 珊瑚贝

Swapping 2 Bytes of Integer


我有一个接收 3 个参数的方法:int x、int n 和 int m。它返回一个 int,其中 x 的第 n 个和第 m 个字节已交换

x 只是一个普通整数,设置为任何值。 n 和 m 是 0 到 3 之间的整数。

例如,设 x 的十六进制表示为 0x12345678,n 为 0,m 为 2。
最后一个和倒数第三个字节应该被交换(n = 78,m = 34)。

我已经弄清楚如何从 x 中提取第 n 个和第 m 个字节,但我不知道如何将所有 4 个字节重新组合成该方法应该返回的整数。

这是我当前的代码:
`

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int byteSwap(int x, int n, int m)
{
    // Initialize variables which will hold nth and mth byte
    int xn = x;
    int xm = x;
    // If n is in bytes, n << 3 will be the number of bits in that byte
    // For example, if n is 2 (as in 2 bytes), n << 3 will be 16 (as in 16 bits)
    xn = x >> (n << 3);
    // Mask off everything except the part we want
    xn = xn & 0xFF;
    // Do the same for m
    xm = x >> (m << 3);
    xm = xm & 0xFF;
}

`

还有一些额外的限制 – 只允许以下:

~ & ^ | ! + << >>

(也就是说没有- * /、循环、ifs等。但是,可以初始化额外的变量,添加仍然可以。)

我的代码可以提取第 n 个和第 m 个字节,但我不知道如何在不使用 ifs 的情况下重新组合所有内容。

  • 一些建议 – 在摆弄位时,使用无符号整数类型是个好主意。 C 不保证有符号整数将使用任何特定的表示 – 如果没有明确定义数字如何转换为位,位摆弄很容易出错。在实践中,对于任何不完全陌生的平台,表示将是二进制补码,但编译器出于优化原因越来越多地利用不确定性。因此,即使您知道您的平台使用二进制补码,您也可能会得到与此不一致的行为,这取决于您的编译器的突发奇想。
  • 是否允许强制转换和指针? (例如 unsigned char* bytes = (unsigned char*)
  • 几件事

    您可以通过使用除字节 m 和 n 之外的所有 FF 的值屏蔽 x 来重新组合
    您可以通过左移 0xFF m 次和 n 次并组合结果然后将其与 0xFFFFFFFF

    进行异或来计算掩码

    1
    2
    3
    4
    5
    6
    7
    8
    int mask = 0;
    int mask_m = 0xFF << (m << 3);
    int mask_n = 0xFF << (n << 3);

    mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

    int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
    return x_swapped;

    仅供参考,当您右移有符号值时,它可能会或可能不会将 1 而不是 0 传播到高位,并且由实现定义。无论哪种方式 0xFF 都会防止这种情况发生。

  • 几件事

    您可以通过使用除字节 m 和 n 之外的所有 FF 的值屏蔽 x 来重新组合
    您可以通过左移 0xFF m 次和 n 次并组合结果然后将其与 0xFFFFFFFF

    进行异或来计算掩码

    1
    2
    3
    4
    5
    6
    7
    8
    int mask = 0;
    int mask_m = 0xFF << (m << 3);
    int mask_n = 0xFF << (n << 3);

    mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

    int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
    return x_swapped;

    仅供参考,当您右移有符号值时,它可能会或可能不会将 1 而不是 0 传播到高位,并且由实现定义。无论哪种方式 0xFF 都会防止这种情况发生。

  • 几件事

    您可以通过使用除字节 m 和 n 之外的所有 FF 的值屏蔽 x 来重新组合
    您可以通过左移 0xFF m 次和 n 次并组合结果然后将其与 0xFFFFFFFF

    进行异或来计算掩码

    1
    2
    3
    4
    5
    6
    7
    8
    int mask = 0;
    int mask_m = 0xFF << (m << 3);
    int mask_n = 0xFF << (n << 3);

    mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

    int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
    return x_swapped;

    仅供参考,当您右移有符号值时,它可能会或可能不会将 1 而不是 0 传播到高位,并且由实现定义。无论哪种方式 0xFF 都会防止这种情况发生。


几件事


您可以通过使用除字节 m 和 n 之外的所有 FF 的值屏蔽 x 来重新组合
您可以通过左移 0xFF m 次和 n 次并组合结果然后将其与 0xFFFFFFFF

进行异或来计算掩码

1
2
3
4
5
6
7
8
int mask = 0;
int mask_m = 0xFF << (m << 3);
int mask_n = 0xFF << (n << 3);

mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
return x_swapped;

仅供参考,当您右移有符号值时,它可能会或可能不会将 1 而不是 0 传播到高位,并且由实现定义。无论哪种方式 0xFF 都会防止这种情况发生。

  • 我还没有尝试过,但它应该可以工作。代码已经屏蔽了除右移 m 和 n 之后的字节之外的所有内容。
  • “当你右移一个有符号值时,它会将 1s 而不是 0 传播到高位” – 除非它没有。右移正符号整数会在零中移动,负符号整数会发生什么是实现定义的。


来源:https://www.codenong.com/21358762/

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?