2017-08-09 16 views
2

大きなタスクの一部として、整数の任意のビットを反転する関数を実装するように求められました。キャッチは、「整数」は、int8_tからuint64_tまでのcのデフォルトの整数型のどれかであり、どの整数型になるかはわかりません。 (実際には、私のコードは、これらのタイプのすべての上でテストされています)uint64_tでのシフトが期待通りに機能しない

これが問題で私の試みだった:このコードは、1とbi番目のビットをXORし、他のビット

//NOTE: g_int is the generic integer, it's typedef'd in a .h file 
g_int flip_bit(g_int b, uint8_t i){ 
    //Code that makes sure i is a valid amount to shift by, there's a macro 
    //that defines the upper bound of i in a .h file. 
    g_int flipped = b^(1<<i); 
    return flipped; 
} 

bに0を設定します。残りの部分は変更せずに、iビット目を反転する必要があります。これに満足して、私はこれらの異なる整数サイズのすべてで自分のコードをテストし、それを入れました。しかし、私のコードがint64_tとuint64_tの両方で失敗したので、十分にテストしてはいけません。

私はint64_tとuint64_tで何が間違っていましたか?メソッドを完全に変更せずにメソッドを動作させるためにできることはありますか?

+0

確かに、私はそれを編集することができます。ジェネリックは、割り当ての型の実際の名前ではありませんでした。私は、その意味を示すようにすぐに変更しました。混乱させて申し訳ありません。 – UnknowableIneffable

+0

.hファイルで 'g_int'はどのように定義されていますか?ビルド全体で常に同じですか? 'flip_bit()'の使用方法に影響を与えるかもしれません。 – chux

+0

ええ、ごめんなさい。私のコードがテストされるときには、同じ名前でテストし、一度に1つずつテストされ、それぞれの異なる整数型のすべてで、さまざまな.hファイルがあることを意味します。私の方法は、それぞれのために働く必要があります。 – UnknowableIneffable

答えて

5

この問題は、タイプ1(int型(適切なマシン上に32ビットを持つ))によって発生します。これは、iの値が32以上の場合にシフト(1<<i)を実行すると、定義されていない動作になります。これはシフトを実行する前にg_intを入力するために1をキャストすることによって簡単に固定することができ

g_int flip_bit(g_int b, uint8_t i){ 
    g_int flipped = b^(((g_int)1)<<i); 
    return flipped; 
} 
+3

唯一の訂正は、整数の幅を超えてシフトすることは*未定義の振る舞い*(ゼロではない)です。 http://port70.net/~nsz/c/c11/n1570.html#6.5.7p4 –

+0

ありがとうございます、私はそれを更新します。 – UnknowableIneffable

+1

*未定義の動作*は "未定義の値"とは異なります。予想外の価値だけでなく、何かが起こる可能性があります。 –

関連する問題