2

乗算の順序が結果に影響を与える可能性があるのはなぜですか?次のコードを検討してください

a=47.215419672114173
b=-0.45000000000000007
c=-0.91006620964286644
result1=a*b*c
temp=b*c
result2=a*temp
result1==result2

result1はresult2 と等しくなければならないことは誰もが知っていますが、次のようになります。

result1==result2 #FALSE!

違いは最小限です

result1-result2 #3.552713678800501e-15

ただし、特定のアプリケーションでは、このエラーが増幅される可能性があるため、同じ計算を実行する2つのプログラム(一方はresult1を使用し、もう一方はresult2を使用)の出力が完全に異なる可能性があります。

なぜそうなのか、そして非常に数値的/科学的なアプリケーションでそのような問題に対処するために何ができるのでしょうか?

ありがとう!

アップデート

良い答えですが、乗算の順序が重要である理由をまだ見逃しています。

temp2=a*b
result3=temp2*c
result1==result3 #True

したがって、コンパイラ/インタプリタはa * b * cを(a * b)*cと見なしているようです。

4

8 に答える 8

9

すべてのプログラミング言語は、浮動小数点数を10進表現から2進表現に変換するときに精度を失います。これにより、演算の順序によって結果が変わる場合を含め、計算が不正確になります(数学は実際にはバイナリで表される浮動小数点値で実行されるため、少なくとも10進数の観点から)。ほとんどの言語は、パフォーマンスを犠牲にして、10進数の精度を維持するためのデータ構造を提供します。DecimalPythonで見てください。

編集:

あなたのアップデートに答えて、正確ではありません。コンピューターは順番に処理を行うため、一連の操作をコンピューターに提供すると、コンピューターは1つずつ順番に進みます。順次コマンド処理以外に実行される操作の明示的な順序はありません。

于 2012-07-24T20:23:00.560 に答える
6

プログラミング言語で浮動小数点数を使用すると、精度が低下します。次のいずれかを実行できます。

精度の低下に対応し、それに応じて同等性チェックを次のように調整します。

 are_equal = (result1-result2)>0.0001

ここで、0.0001(イプシロン)は設定した値です。

または、Pythonで提供されているDecimalクラスを使用します。これは少し遅いです。

于 2012-07-24T20:26:09.110 に答える
6

各乗算は、元の数値の2倍の桁(またはビット)になり、浮動小数点数に割り当てられたスペースに収まるように丸める必要があります。この丸めにより、順序を並べ替えたときに結果が変わる可能性があります。

于 2012-07-24T20:46:07.460 に答える
3

フロートの比較は、常に10 ^ -10のような小さなイプシロンを使用して(あなたが)行う必要があります

于 2012-07-24T20:24:39.053 に答える
1

result1はresult2と等しくなければならないことは誰もが知っていますが、次のようになります。

いいえ、私たち全員がそれを知っているわけではありません。実際、それらは等しくてはいけません。それが等しくない理由です。

あなたは実数で働いていると信じているようです。あなたはそうではありません-あなたはIEEE浮動小数点表現を扱っています。彼らは同じ公理に従わない。それらは同じものではありません。

Pythonは各式を評価し、浮動小数点数になるため、操作の順序が重要になります。

于 2012-07-24T20:24:48.673 に答える
1

理由:おそらく、マシン/Pythonはその精度を処理できません。参照: http: //en.wikipedia.org/wiki/Machine_epsilon#Explicitimation_using_Python

何をすべきか:これは役立つはずです:http://packages.python.org/bigfloat/

于 2012-07-24T20:31:16.960 に答える
1

コンピュータで数値を表現することは、コンピュータサイエンスの大きな研究分野です。これはPythonだけに存在する問題ではありませんが、デフォルトでは任意の正確な計算を実行するにはコストがかかりすぎるため、どのプログラミング言語にもこの特性があります。

アルゴリズムの数値的安定性は、数値的アルゴリズムを考える際のいくつかの制限を反映しています。前に述べたように、Decimalは、銀行のアプリケーションまたはそれを必要とする可能性のあるアプリケーションで正確な計算を実行するための標準として定義されています。Pythonには、この標準の実装があります。

于 2012-07-24T21:16:30.977 に答える
0

以前の投稿でよく答えられたように、これはプログラミング言語で一般的な浮動小数点演算の問題です。型に完全な等式を適用しないように注意する必要がありfloatます。

このような比較がある場合は、与えられた許容値(しきい値)に基づいて比較する関数を使用できます。数値が十分に近い場合は、数値的に等しいと見なす必要があります。何かのようなもの:

def isequal_float(x1,x2, tol=10**(-8)):
    """Returns the results of floating point equality, according to a tolerance."""
    return abs(x1 - x2)<tol

トリックを行います。私が間違っていない場合、正確な許容誤差は、float型が単精度か倍精度かによって異なり、これは使用している言語によって異なります。

このような関数を使用すると、たとえばで計算結果を簡単に比較できますnumpypandasたとえば、次の例を見てみましょう。ここでは、メソッドpd.DataFrame.corr()numpy関数の2つの方法を使用して、連続変数を持つデータセットの相関行列が計算されnp.corrcoef()ます。

import numpy as np
import seaborn as sns 

iris = sns.load_dataset('iris')
iris.drop('species', axis = 1, inplace=True)

# calculate correlation coefficient matrices using two different methods
cor1 = iris.corr().to_numpy()
cor2 = np.corrcoef(iris.transpose())

print(cor1)
print(cor2)

結果は似ているようです:

[[ 1.         -0.11756978  0.87175378  0.81794113]
 [-0.11756978  1.         -0.4284401  -0.36612593]
 [ 0.87175378 -0.4284401   1.          0.96286543]
 [ 0.81794113 -0.36612593  0.96286543  1.        ]]
[[ 1.         -0.11756978  0.87175378  0.81794113]
 [-0.11756978  1.         -0.4284401  -0.36612593]
 [ 0.87175378 -0.4284401   1.          0.96286543]
 [ 0.81794113 -0.36612593  0.96286543  1.        ]]

しかし、それらの正確な平等の結果はそうではありません。これらの演算子:

print(cor1 == cor2)
print(np.equal(cor1, cor2))

ほとんどの場合、False要素ごとに結果が得られます。

[[ True False False False]
 [False False False False]
 [False False False False]
 [False False False  True]]

同様に、np.array_equal(cor1, cor2)も生成されFalseます。ただし、カスタムメイドの関数は必要な比較を提供します。

out = [isequal_float(i,j) for i,j in zip(cor1.reshape(16, ), cor2.reshape(16, ))]
print(out)

[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]

注: numpy配列で浮動小数点要素ごとの比較を実行numpyする関数が含まれています。.allclose()

print(np.allclose(cor1, cor2))
>>>True
于 2019-07-16T15:51:05.393 に答える