Java中的往返转换

时间:2014-06-24 21:24:47

标签: java double

我正在经历:

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

有人可以帮助我理解为什么返回d1d2的布尔比较不相同,尽管情况确实如此?

4 个答案:

答案 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也会给你错误。

浮点数(floatdouble)为stored as a mathematical expression。将double转换为String会截断它。因此,转换后的新双精度值与原始值不同。