C++の浮動小数点型は,float
,double
,long double
の3つ
(C++ではlong double
が正式に規格に加わっている…C言語でも最新の規格では加わってるのかな…).
規格の定義では精度がfloat
≦double
≦long double
となっていればよいので,
float
=単精度(32ビット),double
=倍精度(64ビット)となっているとは限らない(それどころかIEEE形式である必要もない).
ただ,現実的には,普通float
は単精度,double
倍精度になっていると思う.
型名 | サイズ | 値の範囲 | |
---|---|---|---|
float |
32ビット | 符号1+指数部8+仮数部23ビット(10進7桁) | 1.17...×10-38〜3.40...×10+38 |
double |
64ビット | 符号1+指数部11+仮数部52ビット(10進15桁) | 2.22...×10-308〜1.79...×10+308 |
long double |
double と同じ |
なお,浮動小数点形式の定数リテラルのサフィックス“F
”(または“f
”),“L
”(または“l
”)は,
“F
”はfloat
型,“L
”はlong double
型を示すことになっている.
double
型のサフィックスはないようだけど,これはリテラルはF
かL
で指定して,
double
型にはキャストしながら代入されていくのでOKという意味なんだろう.
Intel x86系CPUの場合,double
型としては64ビットなのだけど,
演算の中間結果は80ビット(拡張精度)の浮動小数点レジスタスタックに保持していて,精度が高くなっているかもしれない.
たとえばVisual C++のデフォルトがこの実装になっていて,演算中は80ビットの拡張精度になる.
Visual C++の場合はたいへん複雑なことになっていて,
MSDNによると,古い16ビット版Visual C++では,80ビットのlong double
型というのが存在していたらしいのだけど,
Win32に切り替わったときにlong double
はdouble
型と同じものという仕様に直したという経緯がある.
しかし,Intel系CPUでは拡張精度がデフォルトになっているため,内部的には拡張精度で演算されて
long double
がサポートされていたこと,
Win32でlong double
をdouble
と同じものにしたこと,
互換性のために拡張精度版のランタイムライブラリが残してあることなどが説明してある.
long double
型の扱いについての記載を追加.