• ベストアンサー

ビット操作について

void print_bit(unsigned x) { for(int i=int_bit()-1;i>=0;i--) { putchar(((x>>i) & 1U)?'1':'0');      } } int main(void) { print_bit((~0>>16)); return0; } と入力したのですが、結果が 111111111111111111111111111111 と出てしまうのですが。 自分的には0000000000000000111111111111111と出したいのですが。 どうしたらいいのでしょうか? できるならどうしてこのような結果になったのか教えていただけたらな と思います。よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

処理の順番は「~0 を評価する」→「その値を 16ビット右シフトする」→「得られた値を unsigned にキャストする」となります. ここで問題になるのはこの「~0」が (多くの場合) 負の数になることです. 規格では「左オペランドが負の数の場合, 結果として得られる値は処理系定義である」と規定されています. このプログラムではこの規定が発動されるので, 処理系によって論理シフトだったり算術シフトだったりします. あなたの使っている処理系では, たまたま算術シフトだったのでしょう. ということで, 最初から「0U」と unsigned にしておけば問題なし.

79562
質問者

お礼

わかりました。回答ありがとうございました。

その他の回答 (2)

回答No.2

・算術的右シフト ・論理的右シフト の違いですね。質問者さんの求めているものが論理的右シフトで、今回の結果が算術的右シフトです。 この辺の仕様については私は詳しくないのですが、参考URLによるとCの規格にはシフト演算子が算術シフトなのか論理シフトなのかは規定されていない(コンパイラ依存)そうです。 signedに対する右シフトは算術的右シフトになることが多いので、unsignedにして論理的右シフトのみ扱わせた方が無難です。

参考URL:
http://proger.blog10.fc2.com/blog-entry-62.html
79562
質問者

お礼

そうだったんですか。URLを参考にしたいと思います。回答ありがとうございました。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

整数リテラルの0はint型(負号付整数)です 負数としての0xFFFFFFFFはどれだけ右シフトしても0xFFFFFFFFのままです 希望の結果を得るにはunsigned intとすればいいでしょう int main(void) { print_bit((~0U>>16)); // 整数リテラルにUをつけるとunsigned intになります return 0; }

79562
質問者

お礼

わかりました。回答ありがとうございました。

関連するQ&A