I'm trying to store 3 integers (ie 21 bits each) in one long int
with these macros:
typedef long int Triple;
#define TR_A(o) ((int)((o & 0x7FFFFC0000000000) >> 42))
#define TR_B(o) ((int)((o & 0x000003FFFFE00000) >> 21))
#define TR_C(o) ((int)(o & 0x00000000001FFFFF))
#define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))
So the idea is that o
is 64 bits, and a
,b
,c
are 32 each. When stored inside o
they are 21 bits, and the 64 bits are empty bit, a
, b
, and then c
.
I get a bunch of these errors:
warning: left shift count >= width of type [-Wshift-count-overflow]
#define MK_TR(a,b,c) ((long int)((a<<42) & (b<<21) & c))
^
Is it possible to add something to TR_A
/TR_B
/TR_C
that specifies that o
is long?
Any better way to do this?
I want to be able to return these as simple values, not pointers. Using Linux on PC.
To support two's complement signed ints in the range +/- 1M, both masking and shifting are required:
inline uint64_t make64(int a, int b, int c) {
return ((uint64_t) (a & 0x1fffff) << 42) |
((uint64_t) (b & 0x1fffff) << 21) |
((uint64_t) c & 0x1fffff)
When splitting, the 12 sign bits will need to be restored:
inline int32_t get_a(uint64_t t) {
return (int32_t)((t >> 42 & 0xfffff) | (t & 0x4000000000000000) ? 0xfff00000 : 0);
etc.