【问题标题】:Get signed integer from 2 16-bit signed bytes?从 2 个 16 位有符号字节中获取有符号整数?
【发布时间】:2012-04-01 13:54:49
【问题描述】:

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

【问题讨论】:

  • 请指定语言(并先搜索)。
  • 我已经搜索过了,但我只找到了大约 1 个字节的内容,并且没有合并两个。
  • 标题说的是 16 位字节,但文本暗示的是 8 位字节。是哪个?
  • 如果它们是“16 位有符号字节”,那么您的工作就完成了。但我怀疑你真的像现代世界的大多数人一样拥有 8 位字节,所以你的工作就是狡猾。

标签: c++ binary byte signed


【解决方案1】:
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;

【讨论】:

    【解决方案2】:
     -200 in hex is 0xFF38, 
    

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

    0xFF = 255,
    0x38 = 56
    

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

    所以你的结果是

    value = (highbyte << 8) + lowbyte
    

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

    【讨论】:

      【解决方案3】:

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

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

      如果大于 16 位二进制补码的上限,则减 216

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

      你可以在位级别上做一些技巧,但我认为这没有任何意义。

      以上假设CHAR_BIT = 8,即unsigned大于16位,并且机器和期望结果是二进制补码。


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

      【讨论】:

        【解决方案4】:

        根据您给出的示例,该值似乎已经是 2 的补码。您只需要将高字节左移 8 位,然后将这些值组合在一起。

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

        【讨论】:

          【解决方案5】:

          您可以移动位并屏蔽值。

          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

          【讨论】:

          • 我认为不需要额外的掩蔽。如果将unsigned char 的高值移位到unsigned short,然后将OR 作为unsigned char 的低值移位,然后将结果重新解释为signed short,则结果是有符号的-200。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-06
          相关资源
          最近更新 更多