QT 不清楚的移位运算符行为
QT Unclear shift-operator behaviour
我需要从数组中的一个字节中获取 2 个高位。我有枚举,它定义了这 2 位的所有值:
...
enum elems{
elem1 = 0,
elem2 = 1,
elem3 = 2,
elem4 = 3
}
...
elems getElems(const QByteArray &data)
{
return (elems)(data[3] >> 6);
}
...
qDebug() << (data[3] >> 6); // return 0 or 1 or 2 or 3 (true way)
qDebug() << getElems(data); // return 0 or 1 or -1 or -2 (wrong way)
...
当data[3] == 0
时return0
,当data[3] == 64
时return1
,但data[3] == 192
时return -1
当 data[3] == 128
它 return -2
.
为什么会这样?
QByteArray
是 char
的数组,很可能已签名。因此 192 超出了 char
的范围并返回到 -64
当您 return (elems)(data[3] >> 6)
时,它会执行 arithmetic shift like most compiler implementations on a signed type (because right shift in C++ is implementation defined)。这会将符号位(在本例中为 1,因为 -64)向左传播,使字节中的所有位都为 1,这就是您看到返回 -1 的原因。
如果您只想要 2 个高位,请在返回前屏蔽结果
return (elems)((data[3] >> 6) & 0x03);
或将类型转换为无符号
return (elems)((qint8)data[3] >> 6);
或者这也有效
return (elems)((data[3] >> 6) & 0xFF);
Lưu Vĩnh Phúc 是正确的。您还可以将函数修改为:
return (elems)((unsigned char)data[3] >> 6);
我需要从数组中的一个字节中获取 2 个高位。我有枚举,它定义了这 2 位的所有值:
...
enum elems{
elem1 = 0,
elem2 = 1,
elem3 = 2,
elem4 = 3
}
...
elems getElems(const QByteArray &data)
{
return (elems)(data[3] >> 6);
}
...
qDebug() << (data[3] >> 6); // return 0 or 1 or 2 or 3 (true way)
qDebug() << getElems(data); // return 0 or 1 or -1 or -2 (wrong way)
...
当data[3] == 0
时return0
,当data[3] == 64
时return1
,但data[3] == 192
时return -1
当 data[3] == 128
它 return -2
.
为什么会这样?
QByteArray
是 char
的数组,很可能已签名。因此 192 超出了 char
的范围并返回到 -64
当您 return (elems)(data[3] >> 6)
时,它会执行 arithmetic shift like most compiler implementations on a signed type (because right shift in C++ is implementation defined)。这会将符号位(在本例中为 1,因为 -64)向左传播,使字节中的所有位都为 1,这就是您看到返回 -1 的原因。
如果您只想要 2 个高位,请在返回前屏蔽结果
return (elems)((data[3] >> 6) & 0x03);
或将类型转换为无符号
return (elems)((qint8)data[3] >> 6);
或者这也有效
return (elems)((data[3] >> 6) & 0xFF);
Lưu Vĩnh Phúc 是正确的。您还可以将函数修改为:
return (elems)((unsigned char)data[3] >> 6);