2017-05-29 2 views
0

私の質問は公表されているようです。しかし、私は探していない、私が探しているもの。-0.0と0.0の2つの値/オブジェクトを検出して修正する方法は?

Double.compare()およびDouble.equals()の-0.0には問題があります。小さなコードスニペットで動作を確認し、他の人にこれを共有したいと思います。

私の質問は次のようにセットで-0.0値を回避する方法、である:-0.0がセットに追加する前に0.0であることを強制されるべき

Set<Double> set = new HashSet<Double>; 

。 のための推奨される解決策があります:

if (Math.abs(dv - 0.0) < 1E-14)) dv = 0.0; // possiby a -0.0 value 
set.add(dv); 

か:

if (dv > -1E-14 && dv < 1E-14) dv = 0.0; 
set.add.(dv); 

任意のアイデアウェルカムは。

コードスニペットを共有する:

import java.util.*; 

public class TesterMain 
{ 

public static void main(String[] args) 
{ 
try 
{ 
    ArrayList<Double> list = new ArrayList<Double>(); 
    double eps10 = 1E-10,eps15 = 1E-15,eps16 = 1E-16; 

    Double d_proper_0 = new Double(0.0); 
    Double dv = new Double(-0.0); 
    double a = -0.0,b = 0.0; 

    list.add(d_proper_0); 
    list.add(dv); 

    Double d12 = new Double(12.0); 
    list.add(d12 - eps10); 
    list.add(d12 + eps15); list.add(d12 - eps15); 
    list.add(d12 + eps16); // rounded to 12.0 
    Double dx = new Double(12.123456789); 
    // results in rounded value 12.123456789with 15 after-dot-digits 
    list.add(dx); 

    System.out.println("--- java has 0.0 and -0.0, unfortunately they are different values"); 
    System.out.println("Wrong: equals of " + dv + " and " + d_proper_0 + " is: " + dv.equals(d_proper_0)); 
    boolean res = dv.doubleValue() == d_proper_0.doubleValue(); 
    System.out.println("Correct: '" + dv + ".doubleValue() == " + d_proper_0 + ".doubleValue() ? ' returns " + res); 
    System.out.println("Correct: double variable " + a + " == 0.0 returns: " + (a==0.0)); 
    System.out.println("Wrong: compare " + dv + " with " + d_proper_0 + ": " + Double.compare(dv,d_proper_0)); 
    System.out.println("Wrong: compare double variables " + a + " with " + b + ": " + Double.compare(a,b)); 

    java.util.Collections.sort(list); 
    System.out.println("\n--- Sorting result is correct: "+list.toString()); 

    System.out.println("\ncontains() test: " + dv + ": " + list.contains(dv)); 
    System.out.println("contains() test: " + dx + ": " + list.contains(dx)); 

    System.out.println("\n--- -0.0 values, where do they come from ? Result of calculating or parsing strings"); 
    Double dv3 = new Double(1.0); 
    Double dv4 = dv * dv3; 
    System.out.println("Double objects: " + dv + " * " + dv3 + " = " + dv4); //Result: -0.0 * 1.0 = -0.0 

    try { dv4 = Double.parseDouble("-0.0"); } catch (NumberFormatException e) { System.out.println(e);};  
    System.out.println("Parsing a string results in: " + dv4); //Parsing a string results in: -0.0 

    double db1 = 0.0,db2 = -1.0; 
    System.out.println("double values: " + db1 + " * " + db2 + " = " + (db1 * db2)); // Result: 0.0 * -1.0 = -0.0 

    System.out.println("\n--- How to detect and fix a -0.0 value ?"); 
    Double diff = Math.abs(dv - 0.0); 
    System.out.println("Difference between " + dv + " and 0.0 is: " + diff); 
    if (diff < 1E-14) // if (Math.abs(dv - 0.0) < 1E-14) 
    { dv = 0.0; 
     System.out.println("-0.0 fixed now: " + dv); 
    } 
    System.out.println("\n--- Repeating the tests for the fixed -0.0"); 
    System.out.println("Correct: equals of " + dv + " and " + d_proper_0 + " is: " + dv.equals(d_proper_0)); 
    System.out.println("'" + dv + ".doubleValue() == " + d_proper_0 + ".doubleValue() ?' returns: " + (dv.doubleValue() == d_proper_0.doubleValue())); 
    System.out.println("compare " + dv + " with " + d_proper_0 + ": " + Double.compare(dv,d_proper_0)); 

} catch (Exception e) 
{ 
    e.printStackTrace(); 
} 
    System.exit(1);  
} //---------------------------------------------------- end of main() 
} // end class 

出力は次のとおりです。

--- java has 0.0 and -0.0, unfortunately they are different values 
Wrong: equals of -0.0 and 0.0 is: false 
Correct: '-0.0.doubleValue() == 0.0.doubleValue() ? ' returns true 
Correct: double variable -0.0 == 0.0 returns: true 
Wrong: compare -0.0 with 0.0: -1 
Wrong: compare double variables -0.0 with 0.0: -1 

--- Sorting result is correct: [-0.0, 0.0, 11.9999999999, 11.999999999999998, 12.0, 12.000000000000002, 12.123456789] 

contains() test: -0.0: true 
contains() test: 12.123456789: true 

--- -0.0 values, where do they come from ? Result of calculating or parsing strings 
Double objects: -0.0 * 1.0 = -0.0 
Parsing a string results in: -0.0 
double values: 0.0 * -1.0 = -0.0 

--- How to detect and fix a -0.0 value ? 
Difference between -0.0 and 0.0 is: 0.0 
-0.0 fixed now: 0.0 

--- Repeating the tests for the fixed -0.0 
Correct: equals of 0.0 and 0.0 is: true 
'0.0.doubleValue() == 0.0.doubleValue() ?' returns: true 
compare 0.0 with 0.0: 0 

答えて

0

あなたはSetに要素を追加すると、それはオブジェクトの一意性を決定するためにhashCodeequalsメソッドを使用しています。今、これはDoubleequals()方法のjavadocが言うことである:

D1が+0.0を表す場合d2が-0.0、またはその逆を表す、 等しい試験は、偽の値であっても+ 0.0 == -0.0の値は です。だから、

あなたは0.0と等しい-0.0、例えばを作りたい場合は、手動で値を比較し、変更する必要があります。

Double dv = -0.0; //can be any value 
if(dv.doubleValue() == 0){ 
    dv = +0.0; 
} 
+0

良い、それはイプシロンのものを使用せずに動作します。 – Norbert

0
static double convertNegativeZero(double value) { 
    if (value == 0.0) { 
     value = 0.0; // convert -0.0 to +0.0 
    } 

    return value; 
} 
+0

本当に簡単で、それは動作しますが、私は何のイプシロンを必要としないことを疑問に思います比較する。 – Norbert

+0

@Norbertはい、それはかなりシンプルで便利です。あなたは質問を終わらせてもらえますか? [私の質問に誰かが答えたときにはどうすればいいですか?](https://stackoverflow.com/help/someone-answers) –

+0

私はここで新しいです。今私は投票し、答えを受け入れることを学んだ。 – Norbert

関連する問題