2011-08-07 8 views
11

Python version | Javascript version | WhitepaperPythonとJavascript浮動小数点演算は非常に異なる答えを与えます。私は間違って何をしていますか?

私は、2人のプレーヤーのゲームのGlicko評価を計算するウェブサイトに取り組んでいます。これは、浮動小数点演算(平方根、指数、除算、すべての厄介なもの)が多く含まれています。何故か、私は、行間変換されたアルゴリズムのPython実装とは全く異なる答えを得ています。 Pythonのバージョンは、基本的にアルゴリズムを説明している元のホワイトペーパーにある例の期待される答えを与えていますが、Javascriptのバージョンはかなり外です。

翻訳に間違いがあったのですか、それともJavascriptの浮動小数点数学の精度があまり正確ではありませんか?

Expected answer: [1464, 151.4] 
Python answer: [1462, 155.5] 
Javascript answer: [1470.8, 89.7] 

だから、評価計算は99.6%正確である、それほど悪くはありませんが、分散は2/3でオフになっています!

編集:PyglickoバージョンのRDのデフォルト値が200であることを人々は指摘しています。これは、元の実装者がテストコードを残しているケースで、テストケースがRD 200という値ですが、明らかにデフォルト値は350であるはずです。しかし、私はJavascriptで私のテストケースで200を指定していましたので、ここで問題にはなりません。

編集:map/reduceを使用するようにアルゴリズムを変更しました。格付けはそれほど正確ではなく、分散はより正確で、どちらも識別可能な理由がありません。ウォーバングが始まります。

+1

これは、PythonとJavaScriptが同じ方法で浮動小数点数を処理しないためです。浮動小数点数の仕組みを知っていますか?(そしてそうでないときは) – Halcyon

+2

これは何の意義があるのか​​分かりませんが、rdのデフォルトはPythonでは200、JavaScriptでは350です。 @Frits:どちらもIEEE 754を使用しています。 –

+0

浮動小数点数の仕組みや、たとえば10進数を正確に表すことはできません。 @Daniel Baulig:RDはデフォルトでPythonで200に設定されていますが、これは正しくありませんが、テストケースに使用されます。ホワイトペーパーでは、RDのデフォルト値は350ですが、与えられたテストケースはRDが200のプレイヤーであることを指定しています.Javascriptでは適切なデフォルトを設定しましたが、テストケースでRDを200 –

答えて

7

通常、2つの同様の数字を減算すると、このようなエラーが表示されます。通常、値の間のわずかな違いが増幅されます。たとえば、Pythonで1.2345と1.2346の2つの値があり、javascriptで1.2344と1.2347の値がある場合、その差はそれぞれ1e-4と3 e-4です(つまり1つは3倍です)。

だから私はあなたのコードで減算して、それらの値をチェックする場所を見ています。 (1)減算を避けるために数学を書き直すことができます(何か他の方法で差を計算する式が見つかることがよくあります)。または(2)その特定のポイントの値2つの言語の間で違います(おそらく、piの違いは、他の答えがこのように増幅されていることを示しています)。

ここではあまりありませんが、何かがPythonで整数として扱われるので、違いはありますが、javascriptではfloatとしても可能です。 Pythonでは整数と浮動小数点の間に違いがあります。注意しないと、2つの整数を別の整数(例えば、Pythonでは3/2 = 1)に分けるようなことができます。 javascriptではすべての数値が「本当に」浮動小数点数なので、これは発生しません。

最後に、計算がどのように実行されるかに若干の違いがある可能性があります。しかし、これらは "正常"です - このような劇的な違いを得るには、上記のようなものが必要です。

PS:上のコメントのパラメータrdの初期値についてDaniel Bauligが言ったことにも注意してください。

+0

どちらの言語も浮動小数点実装としてIEEE 754を使用しているので、どちらのシステムでも同じ入力がどのように2つの異なる数になるか分かりません。私はかなり親切なことは、何か非常に重要なことを指摘していると確信しています。 JavaScriptコードでは、PIは非常に大雑把にしか扱われていませんが、PythonコードではMath定数が使用されています。これは非常に間違った結果につながります。 –

+1

には2つの別々の問題があります。結果を正確に複製するという問題がありますが、安定した方法で計算を実装することも重要です。 PIで何桁の有効桁数があるかによって大きく異なる結果が得られれば、システム全体が悪い状態になっていることが示唆されます。 PIを正確に等しくすることによって、元の質問者は両方のケースで同じ結果を得ることができるかもしれませんが、疑わしいコードが残っています。一方、彼が不安定性をよりよく理解すれば、彼は実際に彼が持っているものを改善することができます。 –

+1

も完璧ではありません。 http://en.wikipedia.org/wiki/IEEE_754-2008#Reproducibilityのコメントを参照してください。完全な実装にどれくらい近いか、または同じライブラリを使用しているかどうかはわかりませんが、同じ入力は少し楽観的です。 –

2

私の推測では、JavaScriptバージョンのいくつかの定数に使用している近似が含まれています。特にpi2はちょっと簡単です。私はPythonがこれらの値にdoubleを使用していると信じています。

+0

私はnode.jsでMath.PIを使用してコードを試しました^ 2 - まだ1470.8を得ました – Alnitak

+0

私はもともとMath.whateverをすべての定数に使用していましたが、トラブルシューティングの途中で実際に計算に使用した定数ホワイトペーパー(5つの有効数字、一般的に)。 –

関連する問題