繁体   English   中英

将 8 位有符号整数转换为无符号整数,然后转换为 int32

[英]Convert 8 bit signed integer to unsigned and then convert to int32

我有一个有符号的 8 位整数( int8_t )——它可以是从-55任何值——并且需要将它转换为一个无符号的 8 位整数( uint8_t )。

这个uint8_t值然后被传递到另一个硬件(只能处理 32 位类型)并且需要转换为int32_t

我怎样才能做到这一点?

示例代码:

#include <stdio.h>
#include <stdint.h>

void main() {

    int8_t input;
    uint8_t package;
    int32_t output;

    input = -5;
    package = (uint8_t)input;
    output = (int32_t)package;

    printf("output = %d",output);
}

在这个例子中,我从-5开始。 它暂时被强制转换为251因此可以将其打包为uint8_t 然后将此数据发送到另一块硬件,在那里我不能使用(int8_t)在转换为int32_t之前将 8 位无符号整数转换回有符号整数。 最终,我希望能够获得原始的-5值。

有关更多信息,接收硬件是不允许int8_t的 SHARC 处理器 - 请参阅https://ez.analog.com/dsp/sharc-processors/f/qa/118470/error-using-stdint-h-types

SHARC 处理器上的最小可寻址内存单元是 32 位,这意味着任何数据类型的最小大小都是 32 位。 这适用于像 char 和 short 这样的原生 C 类型。 由于类型“int8_t”、“uint16_t”指定类型的大小必须分别为 8 位和 16 位,因此 SHARC 不支持它们。

如果您想使用 32 位操作取回负号,您可以执行以下操作:

   output = (int32_t)package;
   if (output & 0x80) { /* char sign bit set */
        output |= 0xffffff00;
   }

   printf("output = %d",output);

由于您的接收器平台没有小于 32 位宽的类型,因此您最简单的选择是在发送器上解决此问题:

int8_t input = -5;
int32_t input_extended = input;
uint8_t buffer[4];

memcpy(buffer, &input_extended, 4);

send_data(buffer, 4);

然后在接收端,您可以简单地将数据视为单个int32_t

int32_t received_data;

receive_data(&received_data, 4);

所有这些都假设您的发送方和接收方共享相同的字节序 如果没有,您必须在发送之前翻转发送方的字节序:

int8_t input = -5;
int32_t input_extended = input;
uint32_t tmp = (uint32_t)input_extended;

tmp = ((tmp >> 24) & 0x000000ff)
    | ((tmp >>  8) & 0x0000ff00)
    | ((tmp <<  8) & 0x00ff0000)
    | ((tmp << 24) & 0xff000000);

uint8_t buffer[4];

memcpy(buffer, &tmp, 4);

send_data(buffer, 4);

只需从值中减去 256 ,因为在2 的补码中,n 位负值v存储为2 n - v

input = -5;
package = (uint8_t)input;
output = package > 127 ? (int32_t)package - 256 : package;

这是一种可能的无分支转换:

output = package; // range 0 to 255
output -= (output & 0x80) << 1;

如果设置了第 7 位,第二行将减去 256,例如:

  • 251 设置了第 7 位,251 - 256 = -5
  • 5 清除第 7 位,5 - 0 = 5

编辑:

如果问题是您的代码具有值-55 if语句,那么最简单的解决方案可能是测试result + 5并将if语句更改为010之间的值。

这可能是编译器在优化时会做的事情(因为 0-10 的值可以转换为映射,避免if语句并最小化预测性 CPU 刷新)。


原来的:

如果首先转换为uint8_t然后uint32_t ...

output = (int32_t)(uint32_t)(uint8_t)input;

当然,如果第 8 位被设置,它将保持设置,但符号不会被扩展,因为类型转换操作告诉编译器将第 8 位视为常规位(它是无符号的)。

当然,如果你想更严格,你总是可以享受位掩码的乐趣,但这本质上是一种浪费或 CPU 周期。

编码:

#include <stdint.h>
#include <stdio.h>

void main() {

  int8_t input;
  int32_t output;

  input = -5;
  output = (int32_t)(uint32_t)(uint8_t)input;

  printf("output = %d\n", output);
}

结果为“ output = 251 ”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM