漂浮和双重混乱

Imt*_*ith 9 java type-conversion

在看到下面的代码片段的结果后,我对浮点数的行为感到困惑.

    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!!");
Run Code Online (Sandbox Code Playgroud)

输出:

Oops!!
Matched
Run Code Online (Sandbox Code Playgroud)

这是因为十进制数不能完全代表基本2二进制格式吗?或者这是因为我将float类型变量与double类型进行比较时的精度?如果是,那为什么它适用于下一个变量?

Jon*_*eet 16

这是因为十进制数不能完全代表基本2二进制格式吗?

是.基本上,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
Run Code Online (Sandbox Code Playgroud)

当将最接近第三个的Decimal5值与Decimal10值进行比较时,Decimal5值将转换为Decimal10值0.3333300000,其不等于0.3333333333.这与您的第一个示例类似.

然而,当比较四分之一的值时,Decimal5值0.25000被转换为0.2500000000,这与我们四分之一的Decimal10值相同.这与您的第二个示例类似.

当然,二进制浮点类型比这更复杂,有规范化,次正规数等等 - 但是就你的例子而言,这个类比足够接近.


Pra*_*ker 6

所不同的是5.5可以精确两者来表示floatdouble-而5.4不能精确表示.
参考http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html