[解決済み] Python 3 で浮動小数点値 4*0.1 はきれいに見えるのに、3*0.1 はそう見えないのはなぜですか?
質問
ほとんどの小数は正確な浮動小数点表現を持っていないことは知っています ( 浮動小数点演算は壊れているのか? ).
しかし、なぜ
4*0.1
としてきれいに印刷されます。
0.4
しかし
3*0.1
は、そうではありません。
どちらの値も、実際には醜い10進数表現をしています。
>>> 3*0.1
0.30000000000000004
>>> 4*0.1
0.4
>>> from decimal import Decimal
>>> Decimal(3*0.1)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> Decimal(4*0.1)
Decimal('0.40000000000000002220446049250313080847263336181640625')
解決方法は?
答えは簡単です。
3*0.1 != 0.3
量子化(丸め)誤差のため(一方
4*0.1 == 0.4
なぜなら、2の累乗をかけることは通常 "正確"な操作だからです)。Pythonは
を丸めることができる最短の文字列です。
を表示することができます。
4*0.1
として
0.4
を表示することはできません。
3*0.1
として
0.3
というのも、これらは等しくないからです。
を使用することができます。
.hex
メソッドを使用すると、数値の内部表現を見ることができます(基本的に、Pythonの
正確
バイナリ浮動小数点値で、基数10の近似値ではありません)。これは、ボンネットの下で何が起こっているかを説明するのに役立ちます。
>>> (0.1).hex()
'0x1.999999999999ap-4'
>>> (0.3).hex()
'0x1.3333333333333p-2'
>>> (0.1*3).hex()
'0x1.3333333333334p-2'
>>> (0.4).hex()
'0x1.999999999999ap-2'
>>> (0.1*4).hex()
'0x1.999999999999ap-2'
0.1は0x1.9999999999aの2^-4倍です。末尾の "a" は 10 の桁を意味し、言い換えれば、2 進数の浮動小数点数での 0.1 は次のようになります。
ごくわずかに
最終的に0x0.99が切り上げられ0x0.aになるので)0.1というquot;exact"値より大きくなります。これを2のべき乗である4にかけると、指数は(2^-4から2^-2に)シフトアップしますが、それ以外の数値は変化しませんので、次のようになります。
4*0.1 == 0.4
.
しかし、3を掛けると、0x0.99と0x0.a0(0x0.07)の小さな小さな差が0x0.15の誤差に拡大し、最後の位置で1桁の誤差として表示されるのです。このため、0.1*3は ごくわずかに 丸めた値である0.3より大きい。
Python 3 の float
repr
が設計されています。
ラウンドトリッパブル
つまり、表示された値は元の値に正確に変換できる必要があります (
float(repr(f)) == f
すべてのフロートについて
f
). そのため
0.3
と
0.1*3
と全く同じように、あるいは2つの
異なる
の数値は、往復で同じになってしまいます。その結果、Python 3 の
repr
エンジンは、わずかに見かけ上の誤差があるものを表示するように選択します。
関連
-
python string splicing.join()とsplitting.split()の説明
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み】「RuntimeError: dictionary changed size during iteration」エラーを回避する方法とは?
-
[解決済み】ImportError: PILという名前のモジュールがない
-
[解決済み】TypeError: re.findall()でバイトのようなオブジェクトに文字列パターンを使用することはできません。)
-
[解決済み】「SyntaxError.Syntax」は何ですか?Missing parentheses in call to 'print'」はPythonでどういう意味ですか?
-
[解決済み】django インポートエラー - core.managementという名前のモジュールがない
-
[解決済み] Pythonの@propertyデコレーターはどのように機能するのでしょうか?
-
[解決済み】なぜ10進数は2進数で正確に表現できないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python関数の高度な応用を解説
-
Python Pillow Image.save jpg画像圧縮問題
-
PythonでECDSAを実装する方法 知っていますか?
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み】ImportError: sklearn.cross_validation という名前のモジュールがない。
-
[解決済み】pygame.error: ビデオシステムが初期化されていない
-
[解決済み】"No JSON object could be decoded "よりも良いエラーメッセージを表示する。
-
[解決済み】IndexError: invalid index to scalar variableを修正する方法
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】NameError: 名前 'self' が定義されていません。