双重和浮动值比较

And*_*son 0 java

我刚刚经历了一个比较两个数字的bug,我发现以下内容很有趣:

    assert 1 == 1;//true        
    assert 1d == 1;//true        
    assert 1 == 1f;//true        
    assert 1d == 1f;//true
    assert 1.1 == 1.1;//true        
    assert 1.1d == 1.1;//true        
    assert 1.1 == 1.1f;//false        
    assert 1.1d == 1.1f;//false
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么只有最后两个陈述是假的?

ass*_*ias 13

这是因为四舍五入.

1可以精确地表示为double或float,因此前4个比较按预期工作.

1.1 == 1.1 将double与自身进行比较并按预期工作.

1.1d == 1.1与上面完全相同(d暗示1.1).

最后两次比较将1.1的倍数与1.1的浮点数进行比较.除了它1.1不能完全表示为float(resp.pleip),因此它会四舍五入到最接近的float(resp.pleip) - 但double有一个"更高的分辨率",因此它们不会被类似地舍入.

要查看确切的值:

System.out.println(new BigDecimal(1.1f)); //1.10000002384185791015625
System.out.println(new BigDecimal(1.1d)); //1.100000000000000088817841970012523233890533447265625
Run Code Online (Sandbox Code Playgroud)

正如@yshavit在评论中所建议的那样,当你将double与float进行比较时,float会转换为double(由于数字提升),所以你真的要比较两个双精度:

System.out.println(new BigDecimal((double) 1.1f)); //1.10000002384185791015625
System.out.println(new BigDecimal(1.1d)); //1.100000000000000088817841970012523233890533447265625
Run Code Online (Sandbox Code Playgroud)