在long和double之间输入类型时获得意外结果

时间:2013-08-11 14:54:56

标签: java double type-conversion long-integer

我有这段代码

public class LimitTest{
    public static void main(String[] args){
        long l;
        double d;
        l = 9223372036854775807L;// The largest number a long can hold.
        d = l;
        System.out.println(l);
        System.out.println(d);
        System.out.println(l == d);
    }
}

现在,它产生的结果有点出乎意料,但同样,我对类型转换不是很有经验。

输出

9223372036854775807
9.223372036854776E18
true

现在,打印的两个数字显然是 NOT EQUAL ,那么为什么l == d会返回true

5 个答案:

答案 0 :(得分:5)

变量ld具有不同的类型,因此表达式long == double会将long转换为double ...

P.S。 l是一个糟糕的变量名称imho,因为它在浏览代码时看起来很像1

答案 1 :(得分:2)

l == d会返回true,因为l会自动提升为double,然后会将结果(与d相同)进行比较d

如果您有兴趣,可以阅读JLS中的促销规则:

答案 2 :(得分:2)

  

那么为什么l == d会返回true;

因为long在比较之前转换为double。因此结果是真的。

这在JLS - Section 5.6.2中指定:

  

应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:

     
      
  • 如果任一操作数的类型为double,则另一个操作数将转换为double。
  •   

您看到double的结果不同,因为并非所有long值都可以由唯一的double值表示。因此,对于单个long值,您可能有许多double值。从long转换为double时可能会失去精确度。

来自JLS Section 5.1.2

  

将int或long值扩展为float,或将long值的转换为double ,可能会导致精度损失 - 也就是说,结果可能会失去一些最不重要的价值的一部分。

答案 3 :(得分:2)

为了比较两个值,它们必须具有相同的类型。这里long值被隐式转换为double类型,转换结果给出了与赋值相同的值。

这些值首先是不同的,因为double类型具有较少的“重要性”(它具有用于存储实际数字的53位尾数;其余位用于符号和指数)而不是长(所有64位)。并非所有长值都可以表示为唯一的双精度值。

答案 4 :(得分:2)

92233720368547758079.223372036854776E18 等于

请注意,精度922337203685477的前15位数字是相同的。第一个数字5807的其余部分将四舍五入为6,以便可以附加E18

科学记数法中的

9223372036854775807是:

9.223372036854775807 x 10^18 == 9.223372036854775807E18

比较:

9.223372036854775807E18  
9.223372036854776E18

该值的存储精度高于显示的值,请参阅此说明以获取证据:

    long l;
    double d;
    l = Long.MAX_VALUE;// The largest number a long can hold.
    d = l; //This is implicitly cast to (double)
    System.out.println("long: " + l);
    System.out.println("double: " + d);
    System.out.println("double back to long: " + (long) d);
  

长:9223372036854775807
  双倍:9.223372036854776E18
  双回长:9223372036854775807

还有存储浮点数和双打数的次要问题。虽然整数类型(byte,short,int,long)是精确的,但float和double使用IEEE754尾数指数样式,它允许它们表示更大范围的数字但精度更低。 http://en.wikipedia.org/wiki/IEEE_754-1985