c++ - char 数组到 long 导致意外值

标签 c++ bit-manipulation bit-shift sign-extension

我试图将字节数组转换为长整型

long readAndSkipLong(char*& b)
{
    unsigned long ret = (b[0] << 56) | (b[1] << 48) | (b[2] << 40) | (b[3]<<32) | (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7]);
    return ret;
}

我的转移似乎不对。对于预期值

152  --> 00000000 00000000 00000000 00000000 00000000 00000000 00000000 10011000

我得到:

-104  --> 11111111 11111111 11111111 11111111 11111111 11111111 11111111 10011000 

知道错误在哪里吗?

最佳答案

是因为类型提升和符号扩展。 char 中的每个值数组是有符号的,位移是整数运算。当您使用移位运算符时,它的计算结果为 int ,因为你的 char s 是有符号的,移动它们会产生 signed int

最后(最右边)字节有 1作为标志位。提升为 int 时, 它的值变为 -104通过符号扩展。当您对其余数字进行或运算时,所有 1位不受影响。

为避免此问题,您可以将每个 char s 至 unsigned long在移位和 ORing 之前。

您可以做的另一件事是按位与每个 char0xff喜欢((b[i] & 0xff) << 24) . AND 与 0xff会产生 int , 保持最低有效 8 位不变,左侧为零,无符号扩展。

关于c++ - char 数组到 long 导致意外值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29172142/

相关文章:

c++ - 检查是否至少设置了一点而不跳转

javascript - 使用按位与 1

java - 创建具有大量选项的位掩码

c++ - Bitshifting long int 返回错误的数据

c - 将整个字符数组移位 N 位

c++ - 大数组的 CBLAS 段错误

c++ - 在 C++ 中访问 lambda 之外的 lambda 捕获初始化变量

c++ - 是否可以在不重载的情况下为每个函数设置可变数量的参数?

java - BigDecimal 最佳编码比例

java - 这种使用移位运算的除法近似是如何工作的?