我的变量有2x int16值:
int32_t value = 0x1234ABCD; // a=0x00001234, b=0xFFFFABCD
天真的解决方案是做一个面具:
int32_t a = (value & 0xFFFF0000) >> 16;
int32_t b = (value & 0x0000FFFF);
但有了这个,我没有任何符号扩展,b变为0x0000ABCD
而不是0xFFFFABCD
。
我的下一次尝试是使用中间结构
struct dual_int16 {
long hi:16;
long lo:16;
}
int32_t a = (struct dual_int16)value).lo;
int32_t a = (struct dual_int16)value).hi;
不幸的是我的编译器不允许我这样做"不允许使用struct dual_int16"或"演员类型必须是算术或指针"。
有没有正确的方法在C99中使用符号扩展来提取我的2x int16?
修改
因为我使用的是特定的编译器(ADSP-21xxx)。我没有stdint.h
中定义的所有标准类型,例如int16_t
。我的编译器无法识别int8_t
和int16_t
。
拱门有一个混合32-48位双ALU,大端。
答案 0 :(得分:3)
如果需要带符号的16位值,请使用正确的类型:
#include <stdint.h>
const int32_t value = 0x1234ABCD; // a=0x00001234, b=0xFFFFABCD
const int16_t a = (value >> 16) & 0xffff;
const int16_t b = value & 0xffff;
printf("a=%hd\nb=%hd\n", (short) a, (short) b);
打印:
a=4660
b=-21555
另请注意,我在屏蔽前移位,以减少蒙版的字面大小。对于现代智能优化编译器来说,这可能毫无意义,但这就是我改变它的原因。
我使用int16_t
因为您使用了uint32_t
并提到了C99,这让我相信您应该拥有它。请务必#include <stdint.h>
。
答案 1 :(得分:1)
union
可以解决问题。
union {
int32_t value;
struct {
int16_t v1, v2;
} decomp;
} extract;
/* ... */
extract.value = value;
int32_t a = extract.decomp.v1, b = extract.decomp.v2;
请注意,a
和b
有所需的迹象。
答案 2 :(得分:-2)
short a = (short)( (value >> 16) & 0xFFFF );
short b = (short)( value & 0xFFFF );
int32_t
也不是标准类型(对@coin的评论)。 short/short int
相当于int16_t
。