実数型

概要

数の概念には0.1や1/2(2分の1)といった整数では表せないものがあります。ほとんどの場合は小数や分数で表現できますが、円周率やネイピア数、√2といった無理数を表すことはできません。コンピュータではメモリは有限のため、精度を決めて、結果を丸める必要が出てきます。そこで問題となるのは、どのよう形式で値をメモリに保存し、どこまで精度を持たせるかになります。

大きく分けると実装は小数点数型と有理数型に分かれます。通常の小数点数型は小数部と指数部についてそれぞれメモリで保存する領域決め、計算する方法です。指数部によって小数点の位置が変わるため浮動小数点数と呼ばれます。浮動小数点数で表現できる大きさは指数部に依存し、精度は小数部に依存します。

コンピュータは2進数のほうが計算しやすいため、基数が2の場合がほとんどです。しかし、その方法では単純な小数の足し算ですら、精度の問題で丸め込みが発生するため、別途基数を10にした10進数で計算する型が用意されている場合があります。また、小数点数以下の精度が定まっている計算を想定して、小数点数以下の精度を固定する型もあります。特に通貨計算のために、10を基数として小数点数以下は固定した型(通貨型とも呼ばれます)を用意している言語もあります。

有理数型は少し特殊です。数学の分数と同じように、分子と分母を別々に保存しています。有理数型を使用する利点は、計算結果が有理数となる演算では精度が全く落ちないと言うことです。実際の数は全て分数表記できますので、最も正確に演算できます。

最後に無理数型ですが、有限なメモリ空間では表現不可能なため、存在しません。ただし、精度を引数で渡すと、その精度での円周率やネイピア数を返すという関数が用意されている場合があります。ある意味無理数型と言ってもいいのでは無いかと思います。

実数型の一覧

浮動小数点数の一覧

言語型/クラス別名継承基数サイズ(bit数)精度(bit数)最大表現数最小表現数無限値非数値リテラルライブラリ説明
IEEE754binary16半精度216510
binary32単精度232823
binary64倍精度2641152
binary128四倍精度212815112
decimal32十進単精度1032
decimal64十進倍精度1064
decimal128十進四倍精度10128
Cfloat未定義、通常は321E+371E-5IEEE754 binary16 単精度
double未定義、通常は641E+371E-9
long double未定義、通常は1281E+371E-9
Pythondecimal10精度を指定可能Infinity-InfinityNaN×
RubyFloatNumeric
Object
BasicObject
実装のdobuleに依存。実装のdobuleに依存。実装のdobuleに依存。実装はdoubleを使用しているため、そのままdoubleの範囲に依存します。
CRubyでは、sizeof(void *) >= sizeof(dobule)の環境でのみFlonumという特殊な形式で実装される場合があります。内部で2bit分削ったビット列をVALUEにそのまま保存することで、この2bit分を含まない範囲の浮動小数点数についてはdobuleとしてそのまま扱うことができ、処理を高速化しています。範囲外になる場合は自動的に通常のFloatになります。プログラマーからは(オブジェクトのIDがいつも同じになること以外に)Floatと区別はできません。

固定小数点数の一覧

言語型/クラス別名継承基数サイズ(bit数)精度(bit数)最大表現数最小表現数無限値非数値リテラルライブラリ説明

有理数型の一覧

言語型/クラス別名継承基数サイズ(bit数)精度(bit数)最大表現数最小表現数無限値非数値リテラルライブラリ説明
RubyRational多倍長分子と分母はInteger(FixNumとBigNum)として保存しているため、メモリが許す限りどんな大きな値も処理できます。計算結果が有理数にならないときは自動的にFloatになります。

無理数型の一覧

存在しません。

計算速度

ほとんどの実装で、浮動小数点数はIEEE 754の2進数(基数2)を採用しています。現在あるほとんどのCPUはIEEE 754 倍精度についてコア部分とは別に演算ユニットを持ち、高速に計算することができます。10進数(基数10)の実装であるIEEE 854もIEEE 754に吸収され、同じくCPUには専用の算ユニットがあります。速度については2進数と10進数どちらが速いかは資料を見つけられなかったため、わかりませんでした。通貨計算などの、10進数での表記が重要になる場合を除き、一般の計算には2進数の浮動小数点数を使用しているようです。

有理数型の計算は遅く、多くのメモリが必要になります。速度を期待してはいけません。


間違いを見つけた場合や、ご意見・ご指摘はGitHubレポジトリIssuesへお願いします。