2016-08-10 5 views
3

私は、入力されたリストとそのリストの平均との間の距離であるリストを返そうとするかなり簡単な関数を持っています。コードはほぼです。なぜ結果がややずれているのかについての考えはありますか? [-4.200000000000003、35.8、2.799999999999997、-23.200000000000003、-11.200000000000003]は[4.2、-35.8、-2.8、23.2、11.2]等しくなければならない私のリスト構造の数学演算は数十億分の一になりますか?

+1

のみ53ビット浮動小数点精度のために使用されているため: - ://docs.python https://docs.python.org/2/tutorial/floatingpoint.htmlは[ 'decimal'](HTTPSを見て.org/2/library/decimal.html)モジュール。 – Jan

+0

有限精度の浮動小数点演算の世界へようこそ。 – karakfa

+2

使用することを検討してください[FSUM](https://docs.python.org/2/library/math.html#math.fsum)リンクの重複が主にJavaScriptのであり、この特定のPythonに適用できる解決策を持っていなかったので、私は再び開か – dawg

答えて

7

これが原因である :ここ

def distances_from_average(test_list): 
    average = [sum(test_list)/float(len(test_list))]*len(test_list) 
    return [x-y for x,y in zip(test_list, average)] 

は私の例の結果でありますコンピュータが浮動小数点数を表現する方法まで。

は、彼らはいつもあなたが期待する方法で、正確ではありませんので、平等を確認するか、お金の量のようなものを表すために使用すべきではありません。

はどのようにこれらの番号が使用されていますか?そのような精度が必要な場合は、情報を使用するより良い方法があります。たとえば、等価性のチェックではなく範囲のチェックなどがあります。あなたは完全にバイナリとなることが丸め誤差にどのように表現されるか浮動小数点考慮しない場合

Here is some good reading material on the subject

+1

浮動小数点数は小数点以下の精度ではなく、浮動小数点数の誤差が異なるため、浮動小数点数の小数点以下桁数が小数点として表現されたときに奇妙に見えます。 – Paul

+0

完全に正しい。私は私の答えを更新しました – rscarson

2

浮動小数点は、驚くべき結果につながることができます。浮動小数点の丸め誤差は、直列和で悪化します。

例:

>>> sum([.1]*10) 
0.9999999999999999 # 1.0 expected in decimal 
>>> sum([.1]*1000) 
99.9999999999986  # 100.0 expected 
>>> sum([1, 1e100, 1, -1e100] * 10000) 
0.0     # 20000 expected 

、丸め誤差が加算時解除によって除去することができる他の技術の中で正確な結果(画分モジュールを使用して、小数点モジュールを使用して、等)を取得するための多数の方法があります。あなたは合計で、より正確な結果を得るためのPython数学ライブラリからfsumを使用することができます。

>>> import math 
>>> math.fsum([.1]*10) 
1.0 
>>> math.fsum([.1]*1000) 
100.0 
>>> math.fsum([1, 1e100, 1, -1e100] * 10000) 
20000.0 

fsum機能がレイモンドヘッティンガーのActive Stateレシピに基づいています。 (try math.fsum([1.1,2.2]*1000) ...)ではありませんが、かなり良いです。

+0

私は 'math.fsum'について知りませんでした。とても面白いです。 +1 –

関連する問題