バグ

2017-01-26 12 views
2
floor(-1e-14 % 2) 
Out[1]: 1.0 

floor(-1e-16 % 2) 
Out[2]: 2.0 

私は-1e-160から近すぎるかもしれないが、決して% 2操作後の床の結果は、2(0または1)であることを理解します!バグ

+1

'%'演算子の問題は、 'floor'のバグよりもよく似ています。 – khelwood

+0

私のPython 3.3.1によると、 '-1e-16%2'は' 2'です。 –

+0

おそらく '%2'は' -1e-16'を正の範囲(本質的に '2'を加える)に移動し、丸められ、奇妙な結果が得られます。しかたがない。浮動小数点。 – khelwood

答えて

6

それはあなたが%はとても動作している理由について詳細をお知りになりWhat Every Computer Scientist Should Know About Floating-Point Arithmeticを読むことができるfloor.Checkに%

In [61]: -1e-16 % 2 
Out[61]: 2.0 

In [62]: -1e-14 % 2 
Out[62]: 1.99999999999999 

の結果バグではありません。

decimalモジュールは、10進浮動小数点演算をサポートしています。これは、foatデータ型に比べていくつかの利点があります。だから、浮動小数点の正確な数学のためsys.flaot_infoを使用することがfloat型1の詳細については

sys.float_info

値。

sys.float_info.digは、フロート内で忠実に表現できる小数点以下の桁数を示します。あなたが与えられた精度

で正確な結果を期待していないかもしれません以上の数字を使用して値を含んでいる。これは、私はあなたが-1e-16の結果は2.0すべきではないということだね

In [217]: import sys 

In [218]: sys.float_info.dig 
Out[218]: 15 
+0

私はdownvoteの理由がわかりません。これはOPの質問に正確に答えます(さらに良い答えは '%'がそれに似ている理由を説明するものです)。 –

+0

@JohnColeman私はdownvoteしませんでしたが、それは "フロア"のクールークです。なぜfloor(1.9)return 1とfloor(1.9999)は1を返しますが、floor(1.99999999999999999999)は2を返しますか? – Tagc

+0

@Tagcなぜでしょうか?https://docs.python.org/2/tutorial/floatingpoint.html –

2

を持っているものです計算が、用浮動小数点は奇妙であり、不正確に正確ではありません。 %オペレータstatesの仕様:ABS(のx%のY)< ABS(Y)一方

はフロートのが原因丸めに数値的に真ではないかもしれない、数学的に真です。たとえば、Pythonの浮動小数点数がIEEE 754の倍精度の数値であるプラットフォームを仮定すると、-1e-100%1e100が1e100と同じ符号を持つように計算結果は-1e-100 + 1e100になります。数値的には1e100にちょうど等しい。関数math.fmod()は、代わりに最初の引数の符号と一致する符号を持つ結果を返します。したがって、この場合は-1e-100を返します。どのアプローチがより適切かは、アプリケーションによって異なります。

+0

0.0と0.0を区別することの最終的な限界に達したとき、つまり1.18×10-38の近傍にあり、1e-16がそれ以上のオーダー! –

+0

浮動小数点数で正確に表現できる@YvesSurrelの実数は、均等に分布していません。 0に近い与えられた 'x 'が表現可能であるからといって、' 2 + x'が意味するものではない。 '2 + -1e-16'は' 2.0'と評価されます。 –

+0

良い点! (2.0 + 1e-16)-2.0が正確に0.0であることは事実である –