【发布时间】:2018-04-11 08:42:54
【问题描述】:
我有一个传感器,它以三个字节的形式提供输出。我是这样读的:
unsigned char byte0,byte1,byte2;
byte0=readRegister(0x25);
byte1=readRegister(0x26);
byte2=readRegister(0x27);
现在我想将这三个字节合并为一个数字:
int value;
value=byte0 + (byte1 << 8) + (byte2 << 16);
它给了我从 0 到 16,777,215 的值,但我期望从 -8,388,608 到 8,388,607 的值。我虽然 int 已经被它的实现签名了。即使我尝试像signed int value; 那样定义它,它仍然只给我正数。所以我想我的问题是如何将 int 转换为它的二进制补码?
谢谢!
【问题讨论】:
-
您不应假定
int是2 的补码或任何其他实现细节。这充其量只会导致不可移植和脆弱的代码。只需自己进行算术运算即可得到正确的结果。事实上,你甚至不应该假设它可以容纳一个 3 字节的数字! -
你的架构中的 int 大小是多少?
-
不要假设大小为
int甚至char。使用正确的类型,如uint8_t和int32_t等。 -
@underscore_d there is a proposal 在标准的下一个版本中解决这个问题,因为在实践中,非二进制补码算法似乎不是任何代码的问题 IRL 可能是积极更新或新编写。
-
@Stan 即使使用签名类型,也会发生(未)签名扩展,它仅由编译器执行,而不是程序员。很高兴知道它背后的基本逻辑。有时您必须自己知道如何操作:1) 您无法控制输入值的符号性(第 3 方代码)2) 编译器不支持您所需的整数类型(例如 13 位有符号整数或 256 位有符号整数)。
标签: c twos-complement signed-integer