看到以下代码片段的结果后,我对 float 的行为感到困惑。
float var1 = 5.4f;
float var2 = 5.5f;
if(var1 == 5.4)
System.out.println("Matched");
else
System.out.println("Oops!!");
if(var2 == 5.5)
System.out.println("Matched");
else
System.out.println("Oops!!");
输出:
Oops!!
Matched
这是因为十进制数无法以 base 2 二进制格式准确表示吗? 要么 这是因为我将 float 类型变量与 double 类型进行比较时的精度吗?如果是,那么为什么它对下一个变量工作正常?
最佳答案
Is this because of decimal number that can't be represent exactly in base 2 binary format?
是的。基本上,5.4f
和 5.4d
不相同,因为它们都不是 5.4 的精确表示。
5.5f
和 5.5d
相同,因为它们都是 5.5 的精确表示。
请注意,5.4
与 5.4d
隐式相同 - 浮点文字的默认类型是 double
。任何使用操作数为 float
和 double
的二元运算符都会将 float
提升为 double
并执行对两个 double
值进行运算。
根据十进制 类型来考虑它可能会使事情变得更容易。假设我们有两种类型,Decimal5 和 Decimal10,它们是具有 5 位或 10 位有效数字的十进制数。然后考虑“三分之一”和“四分之一”:
A third:
Decimal5: 0.33333
Decimal10: 0.3333333333
A quarter (showing trailing zeroes just for clarity):
Decimal5: 0.25000
Decimal10: 0.2500000000
将最接近三分之一的 Decimal5 值与 Decimal10 值进行比较时,Decimal5 值将转换为 Decimal10 值 0.3333300000,这不等于 0.3333333333。这类似于您的第一个示例。
但是,当比较四分之一的值时,Decimal5 值 0.25000 将转换为 0.2500000000,这与四分之一的 Decimal10 值相同。这类似于您的第二个示例。
当然,二进制浮点类型比这复杂一点,具有归一化、次正规数等 - 但就您的示例而言,这个类比已经足够接近了。
关于java - float 和双重混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18888001/