まいほびー

体験談を語ったり、身近にあるものを紹介したりします。

HACKING:美しき策謀 第2版 でつまづいた所とその解決方法

タイトル通り、HACKING:美しき策謀 第2版 でつまづいた所とその解決方法を備忘録として書いていきます。

同じところでつまづいている人の参考になればと思います。

p98~99のbitwise.c

つまづいたところ

ソースコード内にある

  • bit_a = ( i & 2 ) / 2;
  • bit_b = ( i & 1 );

という所でつまづきました。(iはforで0~3の間をループ)
コメントにはbit_aは「2番目のビットを取得する」bit_bには「最初のビットを取得する」と書いてありますが、それがどういう意味か私にはちんぷんかんぷんでした。

とりあえず実行結果を見てみると、こんな感じでした。

  • i = 0のとき、bit_a = 0、bit_b = 0
  • i = 1のとき、bit_a = 0、bit_b = 1
  • i = 2のとき、bit_a = 1、bit_b = 0
  • i = 3のとき、bit_a = 1、bit_b = 1

この結果から「( i & 2 ) / 2」「( i & 1 )」の意味を逆算しようと思いましたが、ダメでした。
i = 1のとき、bit_b = ( 1 & 1 )ですから、bit_b = 1だとわかるのですが、それ以外が無理でした。
「1 & 1 = 1」「1 | 0 = 1」のように1と0だけを使った論理演算子の式は理解できるのですが、そこに2や3が含まれてくると、全くわかりません。

解決

2進数で考えると合点が行きました。
0~3を2進数で表すと

  • 0のとき「00」
  • 1のとき「01」
  • 2のとき「10」
  • 3のとき「11」

です。

ですから「1 & 2」を2進数で考えると「01 & 10」、このとき1桁目は「1と0」、2桁目は「0と1」でどちらも数が一致しませんから「1 & 2 = 0」になります。

他に「1 & 3」を2進数で考えると「01 & 11」、このとき1桁目は「1と1」、2桁目は「0と1」で1桁目のみ一致しますから「1 & 3 = 1」になります。

したがってbit_aとbit_bの式の意味はこういうことになります。

  • i = 0のとき、bit_a = ( 0 & 2 ) / 2、bit_b = ( 0 & 1 )。( 0 & 2 )は2進数で表すと( 00 & 10 )つまり0ですから、bit_a = 0。( 0 & 1 )は( 00 & 01 )つまり0ですから、bit_b = 0。
  • i = 1のとき、bit_a = ( 1 & 2 ) / 2、bit_b = ( 1 & 1 )。( 1 & 2 )は2進数で表すと( 01 & 10 )つまり0ですから、bit_a = 0。( 1 & 1 )は( 01 & 01 )つまり1ですから、bit_b = 1。
  • i = 2のとき、bit_a = ( 2 & 2 ) / 2、bit_b = ( 2 & 1 )。( 2 & 2 )は2進数で表すと( 10 & 10 )つまり2進数では10、10進数では2ですから、bit_a = 2 / 2.。2 / 2 = 1よりbit_a = 1。( 0 & 1 )は( 00 & 01 )つまり0ですから、bit_b = 0。
  • i = 3のとき、bit_a = ( 3 & 2 ) / 2、bit_b = ( 3 & 1 )。( 3 & 2 )は2進数で表すと( 11 & 10 )つまり2進数では10、10進数では2ですから、bit_a = 2 / 2、2 / 2 = 1ですから、bit_a = 1。( 3 & 1 )は( 11 & 01 )つまり1ですから、bit_b = 1。

まだ読んでいる途中なので、随時更新していきます。