将 8 位有符号整数转换为无符号整数,然后再转换为 int32
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)
将 8 位无符号整数转换回有符号整数,然后再转换为 int32_t
。最终,我希望能够获得原始的-5
值。
有关详细信息,接收硬件是不允许 int8_t
的 SHARC 处理器 - 请参阅 https://ez.analog.com/dsp/sharc-processors/f/q-a/118470/error-using-stdint-h-types
The smallest addressable memory unit on the SHARC processor is 32 bits, which means that the minimum size of any data type is 32 bits. This applies to the native C types like char and short. Because the types "int8_t", "uint16_t" specify that the size of the type must be 8 bits and 16 bits respectively, they cannot be supported for 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);
所有这些都假设您的发送者和接收者共享相同的 endianness。如果不是,您必须在发送前翻转发件人中的字节顺序:
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's complement中有n位负值v 存储为 2n - 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
编辑:
如果问题是您的代码有 if
语句表示 -5
到 5
的值,那么最简单的解决方案可能是测试 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
”。
我有一个有符号的 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)
将 8 位无符号整数转换回有符号整数,然后再转换为 int32_t
。最终,我希望能够获得原始的-5
值。
有关详细信息,接收硬件是不允许 int8_t
的 SHARC 处理器 - 请参阅 https://ez.analog.com/dsp/sharc-processors/f/q-a/118470/error-using-stdint-h-types
The smallest addressable memory unit on the SHARC processor is 32 bits, which means that the minimum size of any data type is 32 bits. This applies to the native C types like char and short. Because the types "int8_t", "uint16_t" specify that the size of the type must be 8 bits and 16 bits respectively, they cannot be supported for 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);
所有这些都假设您的发送者和接收者共享相同的 endianness。如果不是,您必须在发送前翻转发件人中的字节顺序:
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's complement中有n位负值v 存储为 2n - 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
编辑:
如果问题是您的代码有 if
语句表示 -5
到 5
的值,那么最简单的解决方案可能是测试 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
”。