我有一个传感器,它以三个字节输出。我这样读了:
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转换为它的两个补码?
谢谢!
答案 0 :(得分:7)
您需要执行的操作称为符号扩展。您有24个有效位但需要32位有效位(请注意,您假设int
为32位宽,这并非总是如此;您最好使用{{1}中定义的类型int32_t
})。缺少8个顶部位应该是全部为正值的零或全部为负值。它由24位值的最高位定义。
stdint.h
编辑:请注意,您不能将8位值移位8位或更多位,这是未定义的行为。你必须首先将它转换为更广泛的类型。
答案 1 :(得分:1)
#include <stdint.h>
uint8_t byte0,byte1,byte2;
int32_t answer;
// assuming reg 0x25 is the signed MSB of the number
// but you need to read unsigned for some reason
byte0=readRegister(0x25);
byte1=readRegister(0x26);
byte2=readRegister(0x27);
// so the trick is you need to get the byte to sign extend to 32 bits
// so force it signed then cast it up
answer = (int32_t)((int8_t)byte0); // this should sign extend the number
answer <<= 8;
answer |= (int32_t)byte1; // this should just make 8 bit field, not extended
answer <<= 8;
answer |= (int32_t)byte2;
这也应该有用
answer = (((int32_t)((int8_t)byte0))<<16) + (((int32_t)byte1)<< 8) + byte2;
我可能对括号过于咄咄逼人,但我从不相信自己有班轮操作员:)