以下代码分别使用float
和double
类型的值。
float a=99999.99F;
double b=a;
System.out.println("a : "+a);
System.out.println("b : "+b);
System.out.println("a==b : "+(a==b));
显示以下输出:
a : 99999.99
b : 99999.9921875
a==b : true
执行后,a
和b
的值分别为99999.99
和99999.9921875
,但a==b
会返回true
。
比较表达式a==b
如何返回true
?
答案 0 :(得分:7)
在比较a==b
的最后一行,a
的值在比较之前被隐式提升为双倍。因此,实际上,正在评估的是(((double)a)==b)
,当然,评估为真,因为b
是通过首先将a
转换为double来初始化的。
换句话说,最后一个布尔表达式(a==b)
要求:
是(某些浮点值转换为double)==(相同的浮点值转换为其他地方的double)
答案是:是的。
更新:下面的评论者提出了一个好点:当a
被提升为双倍时,存储的数值实际上不会改变,即使它看起来是因为打印了不同的值。问题在于如何存储浮点数;没有做出这个答案WAAAY太长并且涉及过去我的深度,你需要知道的是,一些简单的十进制值不能以二进制浮点形式完美地表示,无论你有多少位数(就像你可以' t完全代表基数10中的1/3
而没有无限数量的3,如0.333333 ...),所以当你使用float(浮点数的32位表示)分配其中一个值然后您将其转换为double(64位表示),然后使用println
显示该数字的值,您可能会看到更多数字。
println
方法显示最短的十进制数字字符串,转换为计算机内部看到的相同 float (或double)值。虽然在示例中前两次调用println
时将相同的数值作为参数传递,但double
类型具有更高的精度,因此println
需要打印更多数字以显示“最短将转换为(double)99999.99F
的十进制数字字符串。如果您的示例是9999.50,则两个数字都打印相同,因为二进制数字可以表示1/2
就好了。
注意:我甚至不接近浮点数专家;你应该查看(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html),如果你想更深入地了解这里发生的事情。
答案 1 :(得分:4)
这是因为
double b = a;
将浮点值转换(加宽)为double,但在
中b == a
a中的相同浮点值再次转换为double以将其与b进行比较。因此,2次转换的结果是相同的。
答案 2 :(得分:3)
将a
和b
打印为:
System.out.println("a : "+a);
System.out.println("b : "+b);
显示不同的结果是因为Java的默认浮点打印显示的数字足以区分其类型中的数字。在float a=99999.99F;
中,值{9}在float
中无法准确表示,因此会将其转换为最接近的可表示值(99999.9921875),并将a
设置为此值。
打印a
时,只需显示“99999.99”即可显示该值。
然后double b=a;
将b
设置为完全相同的值。但是,由于b
是双倍的,double
中还有其他可表示的值接近99999.99。如果您使用过double b = 99999.99;
,那么double
具有更高精度意味着b
的事实将被设置为更接近99999.99(99999.990000000005238689482212066650390625)的值。但是,您的代码已将b
设置为远远超过99999.99的值。因此,当打印b
时,Java必须使用更多数字来表示其值不是最接近99999.99的double
。
最后,当您比较a
和b
时,比较结果为true,因为a
和b
具有完全相同的值。
总结:a
和b
完全相同,但b
打印的数字更多,因为它在double
中表现得更为精细。
答案 3 :(得分:1)
如果使用不同的值,可能更容易看到发生了什么。例如,如果使用值1234512.345f,则该值将打印为1234512.4,但如果转换为double
,则将打印为1234512.375
。与1234512.345最接近的float
值恰好等于1234512.375;两边的值分别为1234512.25和1234512.5;由于值1234512.4接近1234512.375而不是其中任何一个,因此无需使用更多数字来更准确地表示某些内容。在1234512.375和1234512.4之间有数百万的双重值;因此,较短的表示不足以将数量显示为double
。因此,Java将使用尽可能多的数字来唯一地将值标识为double
。