我的问题似乎是一个宣传。但是我没找到,我在找什么。
Double.compare()和Double.equals()都存在-0.0的困难。我在一个小的代码片段中检查了这个行为,并希望与其他人分享这个行为。
我的问题是,如何在一组中避免-0.0值:
if (Math.abs(dv - 0.0) < 1E-14)) dv = 0.0; // possiby a -0.0 value
set.add(dv);
在将-0.0添加到集合之前,应将其强制为0.0。 是否有推荐的解决方案:
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.123456789012345678);
// results in rounded value 12.123456789012346 with 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.123456789012346]
contains() test: -0.0: true
contains() test: 12.123456789012346: 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
输出是:
epochs = 1
答案 0 :(得分:0)
static double convertNegativeZero(double value) {
if (value == 0.0) {
value = 0.0; // convert -0.0 to +0.0
}
return value;
}
答案 1 :(得分:0)
将元素添加到Set
时,它会使用hashCode
和equals
方法来确定对象的唯一性。现在,这是Double
equals()
方法javadoc所说的:
如果d1代表+0.0而d2代表-0.0,反之亦然 等值测试的值为false,即使+0.0 == - 0.0具有该值 真。
因此,如果你想使+0.0和-0.0相等,你手动需要比较和更改值,例如:
Double dv = -0.0; //can be any value
if(dv.doubleValue() == 0){
dv = +0.0;
}