2017-10-15 7 views
0

私は4つのuint16_tを持っているので、それらを1つの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をエンコードしてから、この方法で戻すことができました。ここでは、2つのエンコードされたフォームをまとめてデコードし、元の操作に戻したいと思います。私は1つのエラーで一束を取っているようだ。

私の出力は0、-15999,16001,16000です。 2つの出力が正しい(0と16000)、2つが1つずれています。

私は最初にint16_tをuint16_t(32768を追加)に変換しようとしましたが、運がないことに注意してください。

答えて

1

あなたはある番号から次の番号に移動しています。数字の19を,23として23と符号化した後、19 + 23 = 421 + 2 = 3のように10進数を符号化した場合とまったく同じです。だから、一番上の数字は「一つずつ」です。不適切なキャリーを避けるために、2つの段階に作用する

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

...:

フル開梱を避けたい場合でも、あなたはまだのような何かを行うことができます。

+0

はい、正しいです。私は16ビット値の真の範囲を越えたことはないので、最初はこのキャリーの問題を避けると考えましたが、今は間違っています。 – AndrewGrant

+0

ええ、それはおそらく2の補完要因でしょうか?例えば。 -1 + -1 = 65535 + 65535 = 131070、mod 65536 = 65534、-2の2の補数。だから切り捨てられた答えではない。しかし、それを計算する際に持ち歩きがありました。 – Tommy

関連する問題