2017-10-15 98 views
0

所以我有4个uint16_t's,我试图将它们存储在单个uint64_t中。我想我有这个工作。存储int16_t在uint64_t的

uint64_t encode(int16_t A, int16_t B, int16_t C, int16_t D){ 
    return (uint64_t)((uint16_t) A) << 48 
     | (uint64_t)((uint16_t) B) << 32 
     | (uint64_t)((uint16_t) C) << 16 
     | (uint64_t)((uint16_t) D) << 0; 
} 

int main(){ 

    int16_t A1 = -32000; 
    int16_t B1 = -31000; 
    int16_t C1 = 16004; 
    int16_t D1 = 16007; 

    uint16_t A2 = 32000; 
    uint16_t B2 = 15000; 
    uint16_t C2 = -4; 
    uint16_t D2 = -7; 

    uint64_t E = encode(A1, B1, C1, D1) 
       + encode(A2, B2, C2, D2); 

    printf("%d\n", (int16_t)((E >> 48))); 
    printf("%d\n", (int16_t)((E >> 32))); 
    printf("%d\n", (int16_t)((E >> 16))); 
    printf("%d\n", (int16_t)((E >> 0))); 
} 

我已经能够编码4 int16_t的,然后让他们回来使用这种方法。现在,我想将两个编码形式加在一起,对它们进行解码,然后返回原始操作。我似乎得到了一堆错误。

我在这里的输出是0,-15999,16001,16000. 两个输出是正确的(0和16000),两个是关闭的。

我会注意到,我试图先将int16_t转换为uint16_t(加32768),但没有运气。

回答

1

你从一个号码进入下一个号码。完全一样的,如果你编码的十进制数19192323,然后加在一起:19 + 23 = 42,但1 + 2 = 3。所以最高的数字是'一个'。

即使你想避免完全拆包,你仍然可以这样做:

result = 
    ((a&0xffff0000ffff0000 + b&0xffff0000ffff0000) & 0xffff0000ffff0000) | 
    (a&0x0000ffff0000ffff + b&0x0000ffff0000ffff) & 0x0000ffff0000ffff)) 

...作用在两个步骤,以避免不当矣。

+0

是的,你是对的。起初我想我会避免这个问题,因为我的数字从来没有超过16位值的真实范围,但我现在看到这是错误的。 – AndrewGrant

+0

是的,这可能是二补的因素?例如。 -1 + -1 = 65535 + 65535 = 131070,其中mod 65536 = 65534,二的补码为-2。所以不是一个截断的答案。但是有计算它的时间。 – Tommy