【平成11年春期の問題より】 問2 負数を2の補数で表すとき,8ビットで表現できる整数の範囲は 10進数でどれか。 ア 0〜255 イ −127〜127 ウ −127〜128 エ −128〜127 ---------------------------------------------------------------------- 【正解】エ ---------------------------------------------------------------------- 【解法】 2の補数に関する基本的な問題である。 結論から言うと、(べき乗を^で表すと)2の補数を使ってnビットで 表現できる整数の範囲は、 −2^(n−1) 〜 2^(n−1)−1 となる。n=8を代入すると、 −2^(n−1) =−2^(8−1) =−2^7 =−128 2^(n−1)−1=2^(8−1)−1 =2^7−1 =128−1 =127 よって、 −128〜127 となるので、正解はエである。 さて、原理を説明する。 8ビットで表現できる数は「負数を考慮しなければ」次のようになる。 ビット列 10進数 00000000 → 0 00000001 → 1 00000010 → 2 : 01111110 → 126 01111111 → 127 10000000 → 128 10000001 → 129 : 11111110 → 254 11111111 → 255 という具合で、0〜255が表現できる。 ここで、負数を表現するために「2の補数」の考え方を導入する。まず、 10進数で1の「2の補数」を求める。2の補数の求め方は、 「0と1を反転して1を加える」 というものである。 1.10進数 1 2.2進数で表現 00000001 3.0と1を反転 11111110 4.1を加える 11111111 → このビット列を「−1」とみなす 1.10進数 2 2.2進数で表現 00000010 3.0と1を反転 11111101 4.1を加える 11111110 (繰上りに注意) → このビット列を「−2」とみなす この考え方で順次計算していくと次のようになる。 ビット列 10進数 00000000 → 0 00000001 → 1 00000010 → 2 : 01111110 → 126 01111111 → 127 10000000 → ? 10000001 → −127 : 11111110 → −2 11111111 → −1 厄介なのは「10000000」である。そのままだと正数128であるが、 「2の補数」を求めると次のようになる。 1.10進数 128 2.2進数で表現 10000000 3.0と1を反転 01111111 4.1を加える 10000000 (繰上りに注意) → このビット列を「−128」とみなす つまり、ビット列「10000000」は、正数128とも負数−128 ともみなすことができるのである。 これまた結論から言うと、「10000000」は負数−128とみなして いる。こうすると先頭ビットを符号フラグ(0なら正数、1なら負数)として 使うことができ、算術シフトの際にも統一した処理が可能であるといった メリットがあるためである。 以上より、ビット列と10進数の対応は次のようになる。 ビット列 10進数 00000000 → 0 00000001 → 1 00000010 → 2 : 01111110 → 126 01111111 → 127 10000000 → −128 10000001 → −127 : 11111110 → −2 11111111 → −1 この考え方はビット数に関わりなく適用できる。 ---------------------------------------------------------------------- 【過去5回の中の類題 その1】 (平成10年春期 問11) 10進数の−100を2の補数表現で8ビットのレジスタに記憶する。 これを右に3ビット算術シフトした結果を10進数で表したものはどれか。 ア −33 イ −13 ウ −12 エ 19 【正解】イ 【解法】 平成7年秋期の問9と同一の問題であり、「2の補数」に関する典型的な 問題である。 問題文の通り進めて行く。 この問題を解くには「10進数←→2進数変換」「2の補数表現」「算術シ フト」の3つのポイントをクリアする必要がある。 1)10進数の100を2進数で表す。 100÷2=50 余り0 50÷2=25 余り0 25÷2=12 余り1 12÷2= 6 余り0 6÷2= 3 余り0 3÷2= 1 余り1 1÷2= 0 余り1 となるので8ビットの2進表現で表すと 01100100 2)これを元に−100を2の補数表現で表す。 01100100 10011011 ← 0と1を反転させる 10011100 ← 2進数の1を加える(繰り上がりに注意) 3)右に3ビット算術シフトする。 10011100 →→→10011 右に3桁シフトするので右の3桁が失われる 11110011 残った数の先頭が1なので左の3桁に1を補う  ̄ ̄ ̄ 4)これを10進数に変換する。 先頭ビットが1だから負数であることはわかる。 11110011 00001100 ← 0と1を反転する 00001101 ← 2進数の1を加える この数は10進数に直すと8+4+1=13 5)以上よりイの−13が正解となる。 シフトについては、 http://www.horse-club.com/josho/98a2/98a2m05.html を参照されたい。 ---------------------------------------------------------------------- 【過去5回の中の類題 その2】 (平成9年秋期 問31) 多くのコンピュータが,演算回路を簡単にするために補数を用いている 理由はどれか。 ア 加算を減算で処理できるから。 イ 減算を加算で処理できるから。 ウ 乗算を加算の組合せで処理できるから。 エ 除算を減算の組合せで処理できるから。 【正解】イ 【解法】 減算の仕組みを簡単に説明しておく。例えば5−1を計算する場合には、 2進法の00000101から00000001を引くという方法はとらない。 むしろ、5に(−1)を加えるという方法をとる。 10進数1の「2の補数」は11111111であるから、5−1の代わりに 5+(−1)=5+(1の「2の補数」)という計算を行う。 00000101 + 11111111 ──────────── 100000100  ̄ ↓ 桁あふれは捨てる → 00000100(=10進数の4) 「桁あふれは捨てる」という考え方が馴染みにくいかとは思う。 このやり方により演算回路は加算だけあればよいことになる。つまり、減算 のかわりにその数の2の補数を加算しているのである。 補数の考え方を取り入れる理由は、このように「減算を加算で処理できる から。」である。よって、正解はイとなる。 ---------------------------------------------------------------------- 【傾向と対策】 ビット処理に関する出題状況は問1に示した。 その中で「2の補数」にかかわる部分だけを再掲する。 平成11年春期 問 2 2の補数 表現できる範囲 <本問> 平成10年秋期 出題なし 平成10年春期 問11 2の補数 <類題> 平成 9年秋期 問 7 2の補数 固定小数点表示法 問12 2の補数 問31 2の補数 補数を使う理由 <類題> 平成 9年春期 問14 2の補数 平成 8年秋期 出題なし 平均すると1回に1問は出題されており、おさえておかねばならない出題 領域のひとつである。 「2の補数」に関しては、なかなかその理屈を理解するのが難しい。むしろ 割り切って問題の解法に徹した方が良い。(そういう領域は二種では実は 少ない。通常は原理的な理解をする方が記憶に定着し応用力がつき、試験 対策としては勝っている。) 二種の問題ならば「反転して1を加える」という手順さえ覚えておけば なんとかなるものである。 ---------------------------------------------------------------------- 【コラム】 「試験が終わって・・・」 春期の試験を受けた後、合格発表までの間はあまり試験の勉強はしたくない というのが本音であろう。このマガジンも1ヶ月弱の休みを入れている。 そうは言っても、そろそろリスタートの時期である。二種の試験は、受験 回数が多くなるにしたがって合格率が下がる傾向がある。惰性に流れる傾向が 強く、弱点を克服しないままに次の試験を受けて落ちるということの繰り返し になりがちなためである。 本来積上げ型の試験であるだけにトータルの勉強時間が多いほど有利なの だが、そうはなっていない。 改めて正解のチェックを行い弱点把握に努めることをすすめる。 |