Web教材一覧ハードウェアとソフトウェア

データの内部表現(数値・上級)

整数の10進・2進・16進数の変換に関しては、「データの内部表現(数値)」を参照してください。

キーワード

シフト演算、小数点以下の基数変換、補数、浮動小数点


シフト演算

シフト演算とは、2進数の計算を高速にする演算方法です。
 例えば、8ビットの2進数
    0001 0010 (=16+2=18)
を左に1ビットシフトすると(右端には0を詰める)、
    0010 0100 (=32+4=36)
になります。これは2倍したことになります。
 同様に、左に2ビットシフトすれば、2=4倍になります。

右に1ビットシフトすると(左端には0を詰める)、
    0000 1001 (8+1=9)
となり、2-1=1/2倍したことになります。

これを組み合わせることにより、
  「元の数Aを左に1ビットした数に、Aを左に2ビットシフトした数を加える」
と、2A+4A=6A の計算をしたことになります。

上の2進数を右に4ビットシフトすると、
    000 0010
   →0010 0000
 また、右に2ビットシフトすると
    0001 00
   →0000 1000
となり、赤のビットが消えてしまい、正確な値になりません。
 これをオーバーフロー、アンダーフローといいます。

小数点以下の変換

2進数→10進数:0.1101→0.812510
2進数→10進数(小数) 右のような表を作成すれば,簡単に計算できます。
練習問題:2進数0.0011→10進数
10進数→2進数:0.812510→0.1101
10進数→2進数(小数) 10進数から,0.5(=1/2),0.25(=1/4),0.125(=1/8),・・・,を負にならないように引いていき,0にすることができれば変換できます。

 たとえば0.8125は,
   0.8125=0.5    (=1/2 → 0.1
         +0.25   (=1/4 → 0.01
         +0.0635 (=1/16→ 0.0001
ですから,0.1+0.01+0.0001=0.1101となります。

しかし,これよりも次の手順(右図)のほうが簡単でしょう。
  1. 10進数を2倍する。整数部分を繰り上がり欄に書き,計算結果の整数部分を0にする。
  2. 整数部分を0にした計算結果を新しい10進数として計算結果が0になるまで,「1」を繰り返す。
  3. 計算結果が0になったら,右図のように上から下へ書き下したものが求める2進数である。
練習問題:10進数0.1875→2進数
〇注意:2進数にできない10進小数がある!
一般的には,上のように2進数に変換できる10進小数はむしろ稀なのです。たとえば10進数の0.1を2進数にしようとすると,
    0.110=0.00011001100110011・・・
のように循環小数になってしまいます。
 コンピュータでの1語のビット数は有限ですから,どこかで打ち切られてしまいます。これを丸め誤差といいますが,10進小数をコンピュータで取扱うときには,あくまでも近似値であり正確な値にはならないのです。
16進数→10進数:0.0816→1/3210
16進数の小数点数を10進数に変換するには、
  0.116=1/1610
  0.0116=1/1610=1/25610
  0.00116=1/1610=1/409610
    :
のように考えます。
  0.0816=8×0.0116=8/25610=1/3210
10進数→16進数:5/3210→0.2816
分母を16の累乗とする分数の和に分解します。
5/32= 4/32→2/16 →2×0.116 →0.216
     +1/32→8/256→8×0.0116→0.0816
    =0.2816
16進数と2進数の変換
16進数と2進数の変換は,10進数をなかがちにして変換することもできますが,2 =16であることを利用すると,たとえば
16進数と2進数の変換の例    11010111010
  =110×2+1011×2+1010
  =616×16+B16×16+A16
  =6BA16
とすることができます。
 また,小数点以下の数では,
   0.110101
  =0.11010100
  =1101×2-4+0100×2-8
  =D16×16-1+416×16-2
  =0.D416
となります。

 すなわち,2進数を16進数に変換するには,小数点を基準に4個ずつに区切り(右側で4個にならないときは0を入れる),その区切りごとに2進数を16進数にすればよいことがわかります。逆に,16進数を2進数に変換するには,16進数の各数を4桁の2進数にすればよいことになります。
練習問題:16進数6BA→8進数

補数

補数の説明図

コンピュータでは,演算回路を簡素化するために,加算回路はあるのですが減算回路は持たず,A-Bの減算をA+(-B)として加算にするのです。では,(-B)をどのように表現するのでしょうか?
 話を簡単にするために,1語を8ビットとします。10進法の5は2進法では00000101になります。唐突ですがそれに11111011を加えると右上図のように結果は0になります。これから,2進数の11111011を10進数の-5であるとすればよいことになります。そのために,8ビット(1語)の先頭ビットが0ならば正数,1ならば負数であるというように決めるのです。このように決めた体系を2の補数表現といいます。00000101の補数は11111011であり,1111011の補数は00000101です。
 補数の求め方は簡単で右下図のように「0/1反転,+1」の操作を行えばよいのです。
 以下,[1語8ビットで2の補数体系の2進数]の例をいくつか示します。これから,この体系で表現できる値の範囲は,-128~0~127であることがわかります。
   00000000     0
   00000001     1
   01111111   127
   10000000  -128
   10000001  -127
   11111111    -1

練習問題:1バイト2の補数での2進数11110111→10進数  

浮動小数点数

固定小数点型では,取扱える数値が限定されますし,非常に大きな数や小さい数を取扱うことができませんので,科学技術計算などでは困ります。このような数値を表現するには,浮動小数点型を用います。

          固定小数点数  浮動小数点数
    用途    事務処理計算  科学技術計算
    小数点   一般には整数値 小数点あり(実数)
    値の精度  正確な値    近似値
    大小範囲  比較的狭い   非常に広い
    計算処理  簡単(高速)  複雑(低速)  *注

例えば、-640を-1.25×2 のように、s・f×reという形式で表現します。ここで、s(-)を符号、f(1.25)を仮数,r(2)を基数、e(9)を指数といいます。すなわち、「±仮数×基数指数」で表現します。

*注
整数演算では、二つの数を2進数に変換して計算し、その結果を10進数に変換するだけでよいのですが、実数計算では、後述のように、指数や仮数など複雑な処理が必要になるので、処理時間が非常に遅くなります。科学技術計算を主とするコンピュータでは、実数計算に特化した演算回路をハードウェアで組み込み高速化を図っています。

浮動小数点数型の表示
浮動小数点数の形式を表現できる範囲の図示

IEEE754(1語32ビット)では、浮動小数点数の表現方法を次のように規定しています。
 符号は、正のとき0負のとき1とします。
 -640は、-1.25×2 は-2.5×2 や-0.625×10 など、多様に表現できますが、仮数を1.Mのように整数部分を1になるように調整することを正規化といいます。そして、M(0.25)の部分を2進数にしたものを仮数部に入れます。正規化を行うのは、仮数部(23ビット)での有効桁数を大きくするためです。
 また、0.001=1.024×2-10 のように、絶対値が小さい数では指数が負になります。それで、2のときE=127、2のときE=128、2-2のときE=125などとなるように、元の指数に127を加えたEを2進数にしたものを指数部(8ビット)に入れます。この操作をバイアスといいます。
 すなわち、-1.25×2 を浮動小数点表示すると、次のようになります。
   S E(指数部、8ビット) M(仮数部、23ビット)
   1     010001000      0100 … 0000
  (-) (9+127=136)    (1.25-1=0.25)

例題
次のIEEE754の32ビットの浮動小数点型数は、10進数ではいくつになるか。
   符号 指数部(8ビット) 仮数部(23ビット)
    0    1000 0110    0010 0000 … 0000

解答
符号が0→正数
指数部=1000 01102=13410=127+7→2
仮数部=0010 0000 … 00002=2-3=0.125
これに整数部の1を加えて、1.125
答 1.125×2=140.625

浮動小数点数の有効桁数
10進数の小数点数は、2進数では循環小数になる場合があります。仮数部のビット数は有限ですから、切られてしまいます。それによる誤差を丸め誤差といいます。
 仮数部が23ビットであり、整数部の1ビットを加えると24ビットになります。224≒10 なので、10進数での有効桁数は7桁になります(2進表示の桁数Bと10進表示の桁数Dの間には、
   2=10 → D=B×log102 となります。log102≒0.3ですから、24桁の2進数は10進数では24×0.3≒7桁になります)。
 また、浮動小数点数の計算では、多様な誤差が発生し、有効桁数は小さくなります。高精度が求められる場合には、1語を64ビットとする倍精度浮動小数点型を用います。
オーバーフローとアンダーフロー
指数部での最大値は1111 11112=25510、最小値は0000 00002=010です。バイアスを戻すと129、-128です。すなわち、絶対値が2129 より大きいときはオーバーフロー、絶対値が2-128 より小さい(0を除く)ときはアンダーフローとなり表現できないのです。倍精度浮動小数点型では指数部のビット数が大きいので、さらに大きい数や小さい数が表現できます。

理解度チェック

第1問

  1. 10進数の23.25を2進数にすると[ 1 ],16進数にすると[ 2 ]になる。

    1 整数23と小数0.25にわけて計算する。

    整数部分
    2 )23
    2 )11 -- 1
    2 ) 5 -- 1
    2 ) 2 -- 1 → 10111
    2 ) 1 -- 0
        0 -- 1
    小数部分
      0.25
     ×   2

      0.50 -- 0
     ×   2      →0.01
      1.00 -- 1
     答:10111.01

    2 2進数を16進数に変換するほうが簡単である。

       1 0111 .0100
       ↓  ↓     ↓
       1  7   . 4
     答:17.4

  2. 2進数での1011+0011は2進数で[ 3 ]となり,16進数での49+7Dは16進数で[ 4 ]となる。

    3の答

        アイウエ
        1011
      + 0011
        1110
    エ:1+1は,2ではなく10になる。1が繰上がる。
    ウ:1+1+1(繰上り)で11になる。
    イ:0+0+1(繰上り)で1。繰上がりはない。
    ア:1+0で1となる。

    4の解1

    いったん10進数にして計算し,それを16進数にする方法も考えられる。(初心者)
      4916→4×16+9=7310
      7D16→7×16+13=12510
      73+125=198
      19810=12×16+6→C616(答)

    4の解2

    16進数を直接に加算してみる。(上級者)
       ア  イ
       4  9
    +  7  D(13)  イ:D16は1310。9+D→2210となるが,
         22 =16+6  それは1616である。
          ↓        すなわち,合計のイは6となり,
    +  1  6        アに116が繰り上がる。
      12         ア:4+7+1(繰上り)→1210となるが,
       ↓          それはC16である。
       C        したがって,49+7D=C6となる。

過去問題:「数値表現・基数変換(上級)」