如何从int32轻松提取2x int16?

时间:2014-12-10 14:34:33

标签: c

我的变量有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_tint16_t

拱门有一个混合32-48位双ALU,大端。

3 个答案:

答案 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;

请注意,ab有所需的迹象。

答案 2 :(得分:-2)

short a = (short)( (value >> 16) & 0xFFFF );
short b = (short)( value & 0xFFFF );

int32_t也不是标准类型(对@coin的评论)。 short/short int相当于int16_t