![](/img/trans.png)
[英]How to convert an unsigned 24 bit int into a signed int and sign extend to 32 bits?
[英]Convert 8 bit signed integer to unsigned and then convert to int32
我有一个有符号的 8 位整数( int8_t
)——它可以是从-5
到5
任何值——并且需要将它转换为一个无符号的 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,例如:
编辑:
如果问题是您的代码具有值-5
到5
if
语句,那么最简单的解决方案可能是测试result + 5
并将if
语句更改为0
到10
之间的值。
这可能是编译器在优化时会做的事情(因为 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.