浮動小数点型と整数型で、互いに誤差なく交換できる最大の整数がいくらなのかを確認。
結論は以下。
・倍精度浮動小数点の場合は ±9007199254740992 (2^53)
・倍精度浮動小数点の場合は ±16777216 (2^24)
これは IEEE754 の仮数部の桁数から導くことができます。
ただ、.net 系で浮動小数点数を書式整形して表示するとおかしなことになる場合があります。
Dim a As Double = 2 ^ 53 Dim b As Double = a - 1 Dim c As Long = b Console.WriteLine("{0:################}", b) Console.WriteLine("{0:################}", c)
結果
9007199254740990 9007199254740991 続行するには何かキーを押してください . . .
b を c に代入すると正しく 9007199254740991 と表示されるのに、b を直接表示すると 9007199254740990 になってしまいます。
上記は倍精度実数の場合ですが、単精度実数の場合でも同様の現象が起こります。
Dim a As Single = 2 ^ 24 Dim b As Single = a - 1 Dim c As Long = b Console.WriteLine("{0:########}", b) Console.WriteLine("{0:########}", c)
16777220 16777215 続行するには何かキーを押してください . . .
10 進数換算で、倍精度の場合 15.6 桁、単精度で 6.9 桁が有効桁数です。従って、10 進数でその桁の数値を全桁を正確に表すことができない桁(倍精度の場合 16 桁目, 単精度の場合 7 桁目) に至る場合は、なんらかの指数計算が行われてしまう、ということのようです。(多分)
まあ正しく表示しろ、って言われると 0.1 は 0.1000000000000000055511151228 になっちゃいますしね。ここは精度範囲外ってことで諦めですね。
したがって、浮動小数点で整数を表現する場合、倍精度の場合 ±9007199254740992 (2^53), 単精度の場合は ±16777216 (2^24)。しかし、10進数表示を考慮に入れるなら、倍精度は 15 桁、単精度は 6 桁以内ということです。
余談ですが javascript だと Number.MAX_SAFE_INTEGER で +9007199254740992 が得られるようです。(.net 系でもこのプロパティ欲しい)