比较Java中的浮点数和双精度数

时间:2013-12-19 13:33:36

标签: java floating-point double

以下代码分别使用floatdouble类型的值。

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

执行后,ab的值分别为99999.9999999.9921875,但a==b会返回true

比较表达式a==b如何返回true

4 个答案:

答案 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)

ab打印为:

的原因
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

最后,当您比较ab时,比较结果为true,因为ab具有完全相同的值。

总结:ab完全相同,但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