2016-08-27 6 views
5

私はMATLABコードをPython 3.5.1に移植していますが、浮動小数点丸め問題を発見しました。 MATLABでPythonでの丸め/切り上げ基準

次数が6位小数点第2位をまでを丸められ、:Pythonで

fprintf(1,'%f', -67.6640625); 
-67.664063 

、一方で、以下の番号は第六小数点第2位をオフを丸めています。

print('%f' % -67.6640625) 
-67.664062 

興味深いことに、数は '-67.6000625'、それはでもPythonで切り上げられている場合:

print('%f' % -67.6000625) 
-67.600063 

...どうしてですか? Pythonで四捨五入する基準は何ですか? (これは16進数値の扱いと関係していると思います)

もっと重要なことに、どうすればこの違いを防ぐことができますか? 私は、MATLABが生成するのと全く同じ出力を再現できるPythonコードを作成することになっています。

+2

私は好奇心が強いので、私はこれもnumpyでも同様に振る舞いました。私が得たものは奇妙だった。 'np.around(a、6)'(aを最初の値にする)は、-67.664062000000001を返します。 2番目の値は-67.600061999999994です。 [公式のpythonのドキュメント](https://docs.python.org/3/tutorial/floatingpoint.html)では、この動作について説明しています。 – Vinay87

+2

私はCとOctaveの両方を試してみましたが、それらはすべてPythonと同じ '-67.664062'を表示します。 – kennytm

+3

トリッキーな浮動小数点の比較が(3.0 * 2.2!= 2.0 * 3.3のように)どうしてあったかを考えると、私はプロジェクトの実行可能性に疑問を呈して始めます。 2つの浮動小数点数を比較するベストプラクティスは、常に差をある程度の許容誤差と比較することです。 – jadsq

答えて

4

Pythonの動作の理由は、浮動小数点数がコンピュータにどのように格納されているのか、ほとんどすべての最新のコンピュータで使用されている標準の数値書式と算術演算を定義したIEEEで定義された標準化された丸め規則です。

数値を効率的にバイナリ形式でコンピュータに格納する必要があるため、コンピュータは浮動小数点数を使用します。これらの数値はプロセッサで処理するのは簡単ですが、小数点以下の数字が多くなるとデメリットがあります。cannot be exactly representedこの結果、時には数字が私たちが考えるべきものから少しずれていることになります。私たちは、むしろそれらを切り捨てるよりも、Pythonでの値を展開する場合

は状況が少し明確になる:あなたが見ることができるように

>>> print('%.20f' % -67.6640625) 
-67.66406250000000000000 
>>> print('%.20f' % -67.6000625) 
-67.60006250000000704858 

-67.6640625は正確に表すことができる数であるが、-67.6000625 ISN」実際には少し大きめです。浮動小数点数の既定の丸めモードdefined by the IEEE stanardでは、5より上の値は切り上げる必要があります。下に切り捨てる必要があります。したがって、-67.6000625の場合は、実際には5に小額を加えたものになるため、切り上げられます。しかし、-67.6640625の場合、それは正確に5に等しいので、タイブレークルールが有効になります。デフォルトのタイブレーカールールは、最も近い偶数に丸められます。 2は最も近いイベント番号であるため、2に切り下げられます。

したがって、Pythonは浮動小数点標準で推奨されているアプローチを採用しています。問題は、あなたのMATLAB のバージョンがでないことです。私は、64ビットのMATLAB R2016aで自分のコンピュータ上でそれを試みたが、私は、Pythonと同じ結果を得た:MATLABは、いくつかの点で、だったよう

>> fprintf(1,'%f', -67.6640625) 
-67.664062>> 

だからそれは(おそらく非標準の異なる丸めアプローチを使用して、思わアプローチ、おそらく標準で指定されている代替案の1つ)、他のすべてのユーザーと同じルールに従うように切り替えました。

+0

うわー、よく説明されています。私は完全に確信しています。はい、私はMATLAB R2011bを使用していますので、少し古いです。私はMATLABが常に正しいと思ったが、私は間違っていた。一つの良いことは、この問題のPythonコードを修正する必要がないということです。 ;-) どうもありがとうございました! – IanHacker

関連する問題