Float有効桁数デモ
0. IEEE 754 double の構成
JavaScript の Number は IEEE 754 倍精度浮動小数点数 (64bit) です。
0 00000000000 0000000000000000000000000000000000000000000000000000
符号 (1bit): 0 = 正, 1 = 負
指数 (11bit): 2の何乗か (bias: 1023を引いた値が実際の指数)
仮数 (52bit): 有効数字 (先頭の 1 は省略 = ケチ表現)
値 = (-1)^符号 × 2^(指数-1023) × (1 + 仮数/2^52)
1. 精度の限界を探る
スライダーで桁数を変えると指数部が変化し、同じ仮数52bitで表せる精度が変わる
基準値: 10^0 = 1e+0
0 00000000000 0000111100000011111100000000000000000000000000000000
符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit| offset (eps倍) | 値 | 基準値との差 | 2進表現 |
|---|---|---|---|
| -2 | 0.99999999999999955591 | -4.440892098500626e-16 | 1 11111111111 1111111011110011111111111100111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit |
| -1 | 0.99999999999999977796 | -2.220446049250313e-16 | 1 11111111111 1111111011110011111111111110111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit |
| 0 | 1.00000000000000000000 | 0 | 0 00000000000 0000111100000011111100000000000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit |
| 1 | 1.00000000000000022204 | 2.220446049250313e-16 | 0 00000000000 0000111100000011111100000001000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit |
| 2 | 1.00000000000000044409 | 4.440892098500626e-16 | 0 00000000000 0000111100000011111100000010000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit |
2. 自由入力で試す
JavaScript の式を入力して結果を確認
結果: 0.30000000000000004
0 01100110011 0011110100110011111100110100001100110011001100110011
符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit3. 有名な浮動小数点トラップ
期待値と実際の計算結果を比較。2進表現で誤差の原因を確認しよう
| 式 | 期待値 | 実際の結果 | 一致? |
|---|---|---|---|
0.1 + 0.2 | 0.3 | 0.30000000000000004 0 01100110011 0011110100110011111100110100001100110011001100110011 符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit | NG |
0.3 - 0.1 | 0.2 | 0.19999999999999998 1 00110011001 1001110010010011111110011001100110011001100110011001 符号: - / 指数: -614 (bias除去: 409 - 1023) / 仮数: 52bit | NG |
0.1 * 3 | 0.3 | 0.30000000000000004 0 01100110011 0011110100110011111100110100001100110011001100110011 符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit | NG |
0.6 / 0.2 | 3 | 2.9999999999999996 1 11111111111 1111000001110100000011111111111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit | NG |
1e15 + 1.1 - 1e15 | 1.1 | 1.125 0 00000000000 0000111100100011111100000000000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit | NG |
9999999999999999 | 10000000000000000 | 10000000000000000 0 11110011100 0011010000010100001100000000100000001110000000110111 符号: + / 指数: 925 (bias除去: 1948 - 1023) / 仮数: 52bit | OK |
0.1 + 0.7 | 0.8 | 0.7999999999999999 1 00110011001 1001111010010011111110011001100110011001100110011001 符号: - / 指数: -614 (bias除去: 409 - 1023) / 仮数: 52bit | NG |
4. n + 1 === n になる境界
仮数部52bitを使い切ると、+1 が仮数の最下位ビットより小さくなり無視される
Number.MAX_SAFE_INTEGER: 9007199254740991 (2^ 53 - 1)
1 11111111111 1111001111110100001111111111111111111111111111111111
符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bitn + 1 !== n の最大 n: 4503599627370496
0 00000000000 0000001100000100001100000000000000000000000000000000
符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bitn + 1 === n の最小 n: 9007199254740992
0 00000000000 0000010000000100001100000000000000000000000000000000
符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit検証: 9007199254740992 + 1 === true (同じ = 精度不足)
指数部が53以上になると、仮数52bitでは1の位を表現できなくなる5. 定数一覧
Number.EPSILON | 2.220446049250313e-16 | 0 00000000000 0000101100000011110000000000000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit |
Number.MAX_SAFE_INTEGER | 9007199254740991 | 1 11111111111 1111001111110100001111111111111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit |
Number.MIN_SAFE_INTEGER | -9007199254740991 | 1 11111111111 1111001111111100001111111111111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit |
Number.MAX_VALUE | 1.7976931348623157e+308 | 1 11111111111 1111111011110111111111111111111111111111111111111111 符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit |
Number.MIN_VALUE | 5e-324 | 0 00000000000 0000000000000000000000000001000000000000000000000000 符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit |