LoginSignup

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

pythonの2**53を超えるFloatの丸めの謎の挙動

解決したいこと

Pythonの浮動小数点の丸めがよくわかりません。
Python 3.8.2です。

以下のようなプログラムを実行します。

A=2**53
print(A)
for i in range(10):
  print(A+i/1)
出力
9007199254740992
9007199254740992.0
9007199254740992.0
9007199254740994.0
9007199254740996.0
9007199254740996.0
9007199254740996.0
9007199254740998.0
9007199254741000.0
9007199254741000.0
9007199254741000.0

浮動小数点の精度が足りなったことで、このような現象が起きているのは理解できますが、
2刻みではなく、$9007199254740996.0$が3回も出力される理由が知りたいです。

0

1Answer

「最近接丸め(偶数)」というルールで端数処理が行われているからでしょう。

最近接丸め(偶数)(Wikipedia IEEE 754 より)

最も近くの表現できる値へ丸める。表現可能な2つの値の中間の値であったら、一番低い仮数ビット(桁)が0になるほうを採用する。これは二進での標準動作かつ十進でも推奨となっている。

とりあえず、出力に現れる数(floatで表現可能な数)を二進数で表してみましょう。

9007199254740992 = 1.0000000000000000000000000000000000000000000000000000 x 2^53
9007199254740994 = 1.0000000000000000000000000000000000000000000000000001 x 2^53
9007199254740996 = 1.0000000000000000000000000000000000000000000000000010 x 2^53
9007199254740998 = 1.0000000000000000000000000000000000000000000000000011 x 2^53
9007199254741000 = 1.0000000000000000000000000000000000000000000000000100 x 2^53

そして、連続する3つの値9007199254740995、9007199254740996、9007199254740997を丸めるとどうなるか考えてみましょう。
まず9007199254740995ですが、9007199254740994と9007199254740996の中間の値なので、一番低い仮数ビットが0になる9007199254740996が採用されます。
次に9007199254740996ですが、これはこのまま9007199254740996となります。
最後に9007199254740997ですが、9007199254740996と9007199254740998の中間の値なので、一番低い仮数ビットが0になる9007199254740996が採用されます。

上記より、連続する3つの値を丸めると、9007199254740996が3回現れることが分かります。

0

Comments

  1. @ufeufhha88fdha

    Questioner
    丸めの種類がこんなにあるんですね。
    理解できました。
    ありがとうございます

Your answer might help someone💌