--:--:--

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進表現
-20.99999999999999955591-4.440892098500626e-16

1 11111111111 1111111011110011111111111100111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
-10.99999999999999977796-2.220446049250313e-16

1 11111111111 1111111011110011111111111110111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
01.000000000000000000000

0 00000000000 0000111100000011111100000000000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit
11.000000000000000222042.220446049250313e-16

0 00000000000 0000111100000011111100000001000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit
21.000000000000000444094.440892098500626e-16

0 00000000000 0000111100000011111100000010000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit
2. 自由入力で試す

JavaScript の式を入力して結果を確認

結果: 0.30000000000000004

0 01100110011 0011110100110011111100110100001100110011001100110011

符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit
3. 有名な浮動小数点トラップ

期待値と実際の計算結果を比較。2進表現で誤差の原因を確認しよう

期待値実際の結果一致?
0.1 + 0.20.3
0.30000000000000004

0 01100110011 0011110100110011111100110100001100110011001100110011

符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit
NG
0.3 - 0.10.2
0.19999999999999998

1 00110011001 1001110010010011111110011001100110011001100110011001

符号: - / 指数: -614 (bias除去: 409 - 1023) / 仮数: 52bit
NG
0.1 * 30.3
0.30000000000000004

0 01100110011 0011110100110011111100110100001100110011001100110011

符号: + / 指数: -204 (bias除去: 819 - 1023) / 仮数: 52bit
NG
0.6 / 0.23
2.9999999999999996

1 11111111111 1111000001110100000011111111111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
NG
1e15 + 1.1 - 1e151.1
1.125

0 00000000000 0000111100100011111100000000000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit
NG
999999999999999910000000000000000
10000000000000000

0 11110011100 0011010000010100001100000000100000001110000000110111

符号: + / 指数: 925 (bias除去: 1948 - 1023) / 仮数: 52bit
OK
0.1 + 0.70.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) / 仮数: 52bit

n + 1 !== n の最大 n: 4503599627370496

0 00000000000 0000001100000100001100000000000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit

n + 1 === n の最小 n: 9007199254740992

0 00000000000 0000010000000100001100000000000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit

検証: 9007199254740992 + 1 === true (同じ = 精度不足)

指数部が53以上になると、仮数52bitでは1の位を表現できなくなる
5. 定数一覧
Number.EPSILON2.220446049250313e-16

0 00000000000 0000101100000011110000000000000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit
Number.MAX_SAFE_INTEGER9007199254740991

1 11111111111 1111001111110100001111111111111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
Number.MIN_SAFE_INTEGER-9007199254740991

1 11111111111 1111001111111100001111111111111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
Number.MAX_VALUE1.7976931348623157e+308

1 11111111111 1111111011110111111111111111111111111111111111111111

符号: - / 指数: 1024 (bias除去: 2047 - 1023) / 仮数: 52bit
Number.MIN_VALUE5e-324

0 00000000000 0000000000000000000000000001000000000000000000000000

符号: + / 指数: -1023 (bias除去: 0 - 1023) / 仮数: 52bit