我正在经历:
Why is a round-trip conversion via a string not safe for a double?
只是想看看Java中发生了什么情况。
public class RounfTripConversion {
public static void main(String[] args) {
Double d1 = 0.84551240822557006;
String s = d1.toString(); // String("r");
Double d2 = Double.parseDouble(s);
System.out.println("Double 1:" + d1);
System.out.println("Double 2:" + d2);
boolean equal = d1 == d2;
System.out.println("Double 1 and 2 are EQUAL is " + equal);
System.out.println("Double 1 - Double 2=" + (d1 - d2));
}
}
输出:
Double 1:0.8455124082255701 Double 2:0.8455124082255701 Double 1 and 2 are EQUAL is false Double 1 - Double 2=0.0
有人可以帮助我理解为什么返回d1
和d2
的布尔比较不相同,尽管情况确实如此?
答案 0 :(得分:2)
因为Double是一个类,所以d1和d2指向不同的对象:
Double d1 = 0.84551240822557006;
String s = d1.toString();
Double d2 = Double.parseDouble(s);
boolean equal = d1 == d2; << FALSE
但是,Double中存储的double的值在比较时将返回true:
boolean equal = d1.doubleValue() == d2.doubleValue(); << TRUE
我认为你感到困惑的是 double 和 Double 之间的区别。其中double是基本类型,只是值,Double是包含值的包装类。
这里发生的是 autoboxing 。你写下以下内容:
Double d1 = 0.84551240822557006;
但真正发生的是:
Double d1 = new Double(0.84551240822557006);
因此,您可以引用包含 double 的 Double 类。
如果你愿意:
double d1 = 0.84551240822557006;
然后你只有值而不是对包含值的类的引用。
答案 1 :(得分:0)
Double值都相同,但没有指向相同的引用。
查看Double
类中的compare()
方法。
答案 2 :(得分:0)
在比较浮点数时,在这种情况下double
装入Double
,您需要注意使用epsilon来比较实际值。原因详见excellent article by Bruce Dawson。
你真正想要的是更像isNearlyEqual
的东西。人们期望等同于传递。至少,你需要传达它不再具有传递性的想法。
为此,你不应该进行精确的比较。从answer:
开始double a = 1.000001;
double b = 0.000001;
double c = a-b;
if (Math.abs(c-1.0) <= 0.000001) {...}
在您的情况下,您要比较两个Double
的引用,它们不会比较实际值。
答案 3 :(得分:-1)
虽然在这种情况下,suresh有一个关于它进行对象比较的观点,即使使用两个double
s也会给你错误。
浮点数(float
和double
)为stored as a mathematical expression。将double
转换为String
会截断它。因此,转换后的新双精度值与原始值不同。