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

Get signed integer from 2 16-bit signed bytes?

本文关键字:符号 获取 整数 字节 2个 16位      更新时间:2023-10-16

所以我的这个传感器通过返回两个(高和低)有符号字节来返回一个介于-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。谢谢你的帮助。

 -200 in hex is 0xFF38, 

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

0xFF = 255,
0x38 = 56

您的传感器返回的不是2个有符号字节,而是一个有符号的16位数字的高位和低位字节。

所以你的结果是

value = (highbyte << 8) + lowbyte

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

根据您给出的示例,该值似乎已经是2的补码。您只需要将高位字节左移8位,然后将这些值进行"或"运算。

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

您可以移位位并屏蔽值。

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();
}

输出:

ffffff 38

-200

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;

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

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

然后,如果这大于16位2的补码的上限,则减去216

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;
}