Javaの浮動小数点数について
そもそも浮動少数点数とは
浮動小数点方式による数のことで、もっぱらコンピュータの数値表現において、それぞれ固定長の仮数部と指数部を持つ、数値の表現法により表現された数である。(wikipediaより)
符号、仮数()、指数を別々の別々のレイアウトで保持することで、大きい範囲の数字を表現することができる
上記の浮動小数点のレイアウトの内訳は以下の形になる
符号(sign): -
仮数(小数部: fraction): 1.110110101
1.110110101の先頭の 1. の部分は必ず同じになるよう指数が設定されているため、省略されて格納される (これをケチ表現というらしい)
これにより 110110101 となり、23桁に足りない分は右側を0で埋めた状態で格納される
指数(exponent): 2の6乗
実際は6に127(バイアス)が加えられて, 133(10000101)が格納される
110 + 1111111 = 10000101 (133)
バイアスについては以下参照
バイアス以外にも、下駄ばき表現、またはオフセット・バイナリなどと呼ばれることがあるとのこと
実際最終的な値の求められ方
1.110110101×2の6乗 = 1110110.101
1110110 = 118
0.101 = 0.625
1 / 2の1乗 + 1 / 2の3乗
118.625に符号をつけて -118.625
IEEE754(単精度)の数値を人力で計算している例
大きい範囲の計算を扱える一方で、浮動小数点数は小数点以下の数字を誤差無く正確に表現することが出来ない。
誤差が起こることを前提としているため、科学計算など近似値がえられれば十分な場面で使用すべきで、金額計算など正確な結果が求められる場面では使用すべきでない。
浮動小数点の誤差(丸め誤差)について
数値計算時に生じる誤差(の少なくとも1つは)とは、有効な精度よりも少ない桁の精度の結果しか得られないことだと理解している。
実数を浮動小数点数すなわち有限桁数の2進数によって計算すると,どうしても誤差が生じる. それを丸め誤差という.たとえば,float 型で表した実数は,その有効数字は約 7 桁であり, それ以上の精度を求めることはできない.
さらに, float 型で表した実数が常に有効数字 6 桁を持っているかというと,そうとは限らない. 始めには 6 桁の有効桁数を持っていた数値が,計算を繰り返すことにより精度が劣化することがある.
この計算繰り返して精度が劣化するタイプの誤差には、桁落ちと情報落ちがある
桁落ち
値が近い二つの数を引き算することにより,その有効桁数が落ちる.これを桁落ちという. 例えば次の計算では, 6 桁の有効桁数を持った2数の引き算の結果の有効桁数が 2 桁となっている.
桁落ちは基本的に引き算で起こる
情報落ち
絶対値が大きな値と小さな値とを加えた場合,小さい方の数値がもつ情報が失われる. たとえば, float 型の精度は約6桁であるから,float 型の数値 77777.7 と 1.23456 とを加えると, 結果も6桁であるから, 77778.9 となる.すなわち, 1.23456 がもつ情報のうちの下4桁の情報が失われている.
Javaの浮動小数点数
準拠している標準規格
Javaの浮動小数点数はIEEE 754に準拠している
Javaでの非数表現は4種類
Each of the four value sets includes not only the finite nonzero values that are ascribed to it above, but also the five values positive zero, negative zero, positive infinity, negative infinity, and NaN.
浮動小数点数の種類
float
32ビット
有効桁数: 約6~7桁の精度
double
64ビット
有効桁数: 約15桁の精度