Reputation: 29116
I have a variable that have 2x int16 values as:
int32_t value = 0x1234ABCD; // a=0x00001234, b=0xFFFFABCD
The naive solution is to do a mask:
int32_t a = (value & 0xFFFF0000) >> 16;
int32_t b = (value & 0x0000FFFF);
But with this, I don't have any sign expansion and b becomes 0x0000ABCD
instead of 0xFFFFABCD
.
My next attempt was to use an intermediate structure
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;
Unfortunately my compiler doesn't allow me to do this "struct dual_int16 is not allowed" or "type of cast must be arithmetic or pointer".
Is there any correct way to extract my 2x int16 with sign expansion in C99?
EDIT
Because I am using a specific compiler (ADSP-21xxx) . I don't have all the standard types defined in stdint.h
such as int16_t
. My compiler does not recognize int8_t
and int16_t
.
The arch has an hybrid 32-48bits dual ALU, big endian.
Upvotes: 2
Views: 850
Reputation: 400009
If you want signed 16-bit values, use the proper type:
#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);
This prints:
a=4660
b=-21555
Also note that I shift before I mask, to reduce the literal size of the masks. This is probably pointless with modern smart optimizing compilers, but that's the reason I changed it.
I used int16_t
since you used uint32_t
and mentioned C99, that really made me believe you should have it. Make sure you #include <stdint.h>
.
Upvotes: 3
Reputation: 6573
short a = (short)( (value >> 16) & 0xFFFF );
short b = (short)( value & 0xFFFF );
int32_t
is not a standard type, as well (comment to @coin). short/short int
is equivalent of int16_t
.
Upvotes: -2
Reputation: 6333
union
will do the trick.
union {
int32_t value;
struct {
int16_t v1, v2;
} decomp;
} extract;
/* ... */
extract.value = value;
int32_t a = extract.decomp.v1, b = extract.decomp.v2;
notice that, a
and b
have desired signs.
Upvotes: 1