2017-10-15 81 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