2012/12/11

文系のための「数値型」(1)

コンピュータ上において、いわゆる「文字」は対応表の位置のコードで表した。
また、この対応表には、「」を文字として表した「数字」も含まれる。
一方、「」を計算のための「数値」として扱う場合には2進数に変換するのであった。

重要な問題は、「数値」と「数字」が異なる体系で表され、
したがって、コンピュータがこの両者を区別するためには、
その体系の定義である「データ型」というのを決める必要があった。

すでに、「文字列型」について説明をしたので、今回は「数値型」について考えてみる。
実は、「数値型」には様々な種類があって、環境によってその定義は異なる
そこで、「文字列型」と同様に、まずはPostgreSQL 9.1データ型から見てみる。
  • 実数型
    • 整数型
      • 狭範囲(smallint):2バイト(-32768〜+32767)
      • 並範囲(integer):4バイト(-2147483648〜+2147483647)
      • 広範囲(bigint):8バイト(-9223372036854775808〜9223372036854775807)
    • 小数点型
      • 固定小数点型
        • decimal:小数点前までは131072桁、小数点以降は16383桁
        • numeric:小数点前までは131072桁、小数点以降は16383桁
      • 浮動小数点型
        • 単精度(real):4バイト(6桁精度)
        • 倍精度(double):8バイト(15桁精度)
PostgreSQLの既定の「数値型」は、いわゆる「実数」しか定義されていないが、
数値計算ライブラリの「R」などなどでは、「虚数」を定義している場合もある。
...が、話が拗れるので、ここでは割愛。「実数型」のみを扱う。今は不要。

さて、これら複数の数値型適切なものを選ぶには、実際に扱うデータを観察し
それぞれの数値型と見比べ、適切な「桁数」と「精度」を持つものを選ぶことが重要。
また、データ量が増えてくると、処理効率も考慮する必要があるかもしれない。

まず、「整数型」から見てみる。「整数値」には、範囲に応じて3つの型が存在する。
どれを使うべきかは、実際のデータの範囲と見比べて考えるべきであるが、
私がこれまでに扱ってきたデータで「integer」の範囲を超えたことはない。

「整数型」で気を付けるべき点は、数字の有効桁数を考えるだけ
これは、文字列型を扱ったときと同じ注意事項である。難しくない。

次に、「小数点型」について整理してみる。やはり、複数の型が用意されている。
実は、整数型と比較して「小数点」が含まれる数値は、少々、厄介。
コンピュータは、「1」と「0」しか扱えない。したがって、「.(点)」は表せない

アイデアは二つある。一つ目は、「整数部」と「小数部」を分ける方法であり、
二つ目は、「指数」によって表現し、「仮数部」と「指数部」に分ける方法である。
それぞれの方法を、「固定小数点」と「浮動小数点」呼ぶ。

まずは、「固定小数点型」は、「整数部」と「小数部」に分けるだけなので簡単。
この方法、数値は「正しい」が、扱える範囲がかなり狭いという問題がある。
通常は、資金管理システムなど、厳密な数字を扱う場合に用いる

なお、PostgreSQL では、「decimal」と「numeric」の二種類が用意されているが、
両方とも等価であるので、いずれを用いても構わないことになっている。
PostgreSQL では、「固定小数点型」の処理速度は、「浮動小数点型」と比較して低速

一方、「浮動小数点型」は、数値を「指数」によって表現する方法であり、
仮数部」と「指数部」に分けて「1」と「0」の2進数に直す。
この方法、「指数」というのを理解していないと、何のことか解らない。

指数」というのは、簡単に言うと、「ある数が何回掛けられているか?」ということ。
つまり、「1000」という数値は、「10」が「3」回掛けられた数値であり、
指数表現を用いると、「」 のように表現することができる。

この時、「10」の部分のことを「」と呼び、「3」の部分のことを「指数」と呼ぶ。
高校の数学で習った気もする。もちろん、「低」の部分を「2」にすることも可能
実は、コンピュータのように2進数の世界ではこちらの方が便利

例えば、以下のように表現することができる。
よく考えてみれば、それほど難しいものでもあるまい。


1.101011」の部分を「仮数」と呼び、「16」の部分が「指数」である。
ここで、コンピュータ上では「」は「2」と決まっているので、
元の数値を復元するためには、「仮数部」と「指数部」さえ解れば良い

この方法、「固定小数点型」よりもビット数を節約できるので、
固定小数点」による表現方法に比べて、表現できる数値の幅が広い。
コンピュータの性能が低かった時代に生み出された画期的な方法。

現在でも、「浮動小数点型」は数値の一般的な表現方法である。
指数部によって、小数点の位置が変わることことから、
固定」に対して「浮動」なのである。

さて、話が逸れたが、この表現方法、実は大きな問題がある。
固定小数点型」と異なり、近似解として元の数を表しているため、
実を言うと、元の数値を正確に表現できているとは限らない

そこで、出てくるのが「精度」という言葉。これが重要。
6桁精度」の場合、6桁目までは信用しても良いが、それ以降は「誤差」。
例えば、「0.1234567」という数の場合、最後の「7」は正しいかは不明。

この精度の差が「real型」と「double型」の大きな違い。
double」という言葉の通り、  「real型」の倍の精度を持っている。
この知識は極めて重要である。出てきた数値を鵜呑みにすることは極めて危険!

例えば、GPSで取得した緯度経度の座標値を表現する場合に、
6桁精度」の「浮動小数点型」を用いてしまうとかなり厄介なことになる。
やはり、この場合には、「15桁精度」の「double型」を使った方が安全

さて、今回は、数値型について整理をしてみた。注意すべき点は3つ。

一つ目は、文字列型の時にも書いたように表現できる桁には限界があること。
二つ目は、「固定小数点型」と「浮動小数点型」の二種類が存在すること。
三つ目は、「浮動小数点型」の場合には「桁精度」があるということ。

この3つのポイントが理解できていれば良い。
次回は、Python における「数値型」について整理し、
簡単なプログラムを書いてみることにする。

1 件のコメント:

  1. 勉強になりました。ありがとうございます

    返信削除