从2个16位有符号字节中获取有符号整数?

时间:2012-03-16 00:30:16

标签: c++ binary byte signed

所以这个传感器通过返回两个(高和低)有符号字节返回-500-500之间的有符号值。我如何使用它们来确定实际值是多少?我知道我需要做2的补充,但我不确定如何。这就是我现在所拥有的 -

real_velocity = temp.values[0];
    if(temp.values[1] != -1)
        real_velocity += temp.values[1];

    //if high byte > 1, negative number - take 2's compliment
    if(temp.values[1] > 1) {
        real_velocity = ~real_velocity;
        real_velocity += 1;
    }

但它只会返回积极的负值。因此,例如,-200返回字节255(高)和56(低)。添加这些是311.但是当我运行上面的代码它告诉我-311。谢谢你的帮助。

5 个答案:

答案 0 :(得分:4)

 -200 in hex is 0xFF38, 

你得到两个字节0xFF和0x38, 将这些转换为十进制可能会识别它们

0xFF = 255,
0x38 = 56

你的传感器没有返回2个有符号字节,而只是一个有符号16位数字的高低字节。

所以你的结果是

value = (highbyte << 8) + lowbyte

值是一个16位有符号变量。

答案 1 :(得分:2)

根据您提供的示例,该值似乎已经是2的补码。您只需要将高位字节左移8位并将值一起移位。

real_velocity = (short) (temp.values[0] | (temp.values[1] << 8));

答案 2 :(得分:1)

您可以移动这些位并屏蔽这些值。

int main()
{
    char data[2];
    data[0] = 0xFF; //high
    data[1] = 56; //low
    int value = 0;

    if (data[0] & 0x80) //sign
        value = 0xFFFF8000;

    value |= ((data[0] & 0x7F) << 8) | data[1];

    std::cout<<std::hex<<value<<std::endl;
    std::cout<<std::dec<<value<<std::endl;
    std::cin.get();
}

输出:

ffffff38

-200

答案 3 :(得分:0)

real_velocity = temp.values[0];
real_velocity = real_velocity << 8;
real_velocity |= temp.values[1];
// And, assuming 32-bit integers
real_velocity <<= 16;
real_velocity >>= 16;

答案 4 :(得分:0)

对于8位字节,首先只需转换为unsigned

typedef unsigned char Byte;
unsigned const u = (Byte( temp.values[1] ) << 8) | Byte( temp.values[0] );

然后如果它大于16位二进制补码的上限,则减去2 16

int const i = int(u >= (1u << 15)? u - (1u << 16) : u);

你可以在比特级做技巧,但我认为没有任何意义。

以上假设CHAR_BIT = 8,unsigned超过16位,并且机器和所需结果是2的补码。


#include <iostream>
using namespace std;

int main()
{
    typedef unsigned char Byte;
    struct { char values[2]; } const temp = { 56, 255 };

    unsigned const  u = (Byte( temp.values[1] ) << 8) | Byte( temp.values[0] );
    int const       i = int(u >= (1u << 15)? u - (1u << 16) : u);

    cout << i << endl;
}