我刚刚经历了一个比较两个数字的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)