2012-03-26 15 views
1

別の開発者が、文字列化された倍精度文字列を含む一連の文字列を返すアルゴリズムを私に与えました。これらの文字列出力に対して単体テストを構築しています。私が単位テストを実行する時間の約80%がすべて合格します。返された文字列の二重の部分には、時間のわずか20%のばらつきが発生します。たとえば:実行間の二重計算のわずかな違い

Expected: ((B,D),(C,A)); : 0.05766153477579324 
Found: ((B,D),(C,A)); : 0.05766153477579325 

Expected: (B,(C,(A,D))); : 0.0017518688483315935 
Found  (B,(C,(A,D))); : 0.001751868848331593 

私は、二重計算が不正確であることができることを知っているが、私は彼らがバリアントであることの聞いたことがありません。アルゴリズム作成者は、アルゴリズムが決定論的であると確信しています。 doubleがtoStringedされる方法は次のとおりです。

for(Tree gt: geneTrees){ 
     double prob = probList.next(); 
     total += prob; 
     result.append("\n" + gt.toString() + " : " + prob); 
    } 

私はこの変化がどのように可能か説明します。何か案は?

+3

あなたはに*、あなたが実行間同じ入力を取得することを確認するために、文字列の入力を記録することができます同じ注文*? –

+0

異なる注文がどれほど変わるかを確認するhttp://vanillajava.blogspot.co.uk/2012/03/different-results-summing-double.html 1001個の値をランダムな順序で追加し、1000個以上の異なる合計を生成します。 ;) –

答えて

3

あなたがやっている合計に基づいて、私はこれは二重の加算が非常に可換でも連想でもないという問題が原因だろうと考えています。異なる順序。

基本的にユニットテスト用に小さなイプシロンを追加してください。

+0

+1。興味深い洞察 – aioobe

+0

これは問題でした。開発者は、倍数が乗算される順序を決定するHashMapを繰り返していました。 TreeMapに切り替えられ、毎回計算が再現可能です。 – Dejas

+0

'LinkedHashMap'も動作します。それはハッシュベースですが、その反復順序は一貫しています。 –

0
I am at a bit of a loss explain how this variation is possible. 

これまでのように、「それらをすべて支配する」という1つのCPUアーキテクチャ/ OS /プログラミング言語があるまでは、このような問題が起こります。あなたは100万小数点以下を100%にする方法を見つけようと思っていますが、これは時間の無駄だと思います。

Any ideas? 

精度を選んで、その精度内で数字が失敗した場合にのみ、差分を失敗します。あなたが第2まで気にしている(または測定できる)場合、小数点第10位まで計算された数値を持つ必要はありません。

たとえば、あなたがこれを持っている...

つまり
Expected: ((B,D),(C,A)); : 0.05766153477579324 
Found: ((B,D),(C,A)); : 0.05766153477579325 
              ^
              | 
              | 
           If this was a 9...would it change the behavior 
           of whoever is using your calculation? 

...

Double expected = 0.05...... 
Double actual = Double.parseDouble(valueFromFile); 

// Instead of doing this.... 
if(!expected.equals(actual)) { 
    // fail test.. 
} 

// Do this (only substitute .0001 with whatever you think an acceptable number is 
// based off of the precision possible of the measurement of your input).... 
if(Math.Abs(expected - actual) > .0001) { 
    // fail test... 
} 
+3

IEE 754 *は、浮動小数点の場合に「すべてを支配する」標準です。 –

関連する問題