2017-07-21 17 views
0

私は3バイト配列を変換し、3バイト配列を単一のint32として返さなければならない関数に取り組んでいます。 コードは次のとおりです。 pbDataはバイト配列へのポインタです。最も重要な符号ビット(リント警告)を設定する

const byte bMSBitPosNeg = 0x80; 
const byte bMSBNeg = 0xFF; 
int32 i32Num = 0; 

//Big - Endian 
if (pbData != NULL) 
{ 
    if ((pbData[0] & bMSBitPosNeg) == bMSBitPosNeg) //Negative 
    { 
     i32Num |= (bMSBNeg * 0x1000000); //Force MSB to 0xFF as 3 bytes are 
             //converted to 4 bytes 
    } 

    i32Num |= (pbData[0] << 16); 
    i32Num |= (pbData[1] << 8); 
    i32Num |= (pbData[2]); 

} 
return i32Num; 

入力:{0x00,0xBB、0xA3の} 出力:48035 //正数

入力:{0xFFで、0x44,0x5d} 出力:-48035 //負数

コードは期待どおりに動作しますが、私はリント警告を受け取ります。 警告648:操作のための計算定数のオーバーフロー: '乗算'

機能は必要ですが、警告は必要ありません。どのように抑制しますか?

+0

あなたの '0x1000000'定数に' UL'サフィックスを使用してください –

+0

対応するシフトとして乗算を行うと、意味が成り立ちますか?あなたは '** int **'を使って作業していることを覚えておいてください。これは、**署名された** 32ビットタイプです(ほとんどのプラットフォームで)。 –

+0

一般的なヒント:ビットを扱うときは、*常に*明示的に符号なしのデータ型を使用します。 –

答えて

2

あなたはビットシフトで乗算を置き換える、あるいは読みやすくするため、手動でビットパターンを計算することができます

const int32 bMSBNeg = (int32)0xFF000000; 

また、上位3つのバイトに番号を構築し、次にシフトすることにより、これらすべての計算を回避することができます

if (pbData != NULL) { 
    i32Num = ((pbData[0] << 24) | (pbData[1] << 16) | (pbData[2] << 8))/256; 
} 

注:代わりに、256で割る8によってシフトは標準に従って実装定義挙動であろう部門と8ビットでそれダウン。

+1

あなたの最初の行は範囲外割り当てです(負の値をアンパックする際にいくつかの問題があります; OPが実装定義の動作を避けたい場合は注意が必要です) –

+0

C11ドラフト規格n1570:* 6.5.7ビットシフト演算子5 E1 >> E2の結果はE1右シフトE2ビット位置です。 [...] E1に符号付きの型と負の値がある場合、結果として得られる値は実装定義です* – EOF

+1

@EOF実装定義の振る舞いを持つ厄介な標準で、私はもう一度私を受け取ります。私は代わりに256で除算を使用する必要があります。 – dasblinkenlight

関連する問題