Java Math.floor函数在双变量上未按预期工作

Java Math.floor函数在双变量上未按预期工作,java,Java,这是我用上面的代码得到的输出。这里的double:和float:部分是Math.floor(d)和Math.floor(f)的输出。通过main()此命令System.out.println(arequalbythreedecimalplaces(3.174D,3.175D))给出的值发送的第二组值发生意外行为。对于doublevariabled来说,输出应该与floatvariablef的输出一样,但是Math.floor(d)返回0.000000我期望的1.000000用以下内容替换上一次打

这是我用上面的代码得到的输出。这里的
double:
float:
部分是
Math.floor(d)
Math.floor(f)
的输出。通过
main()
此命令
System.out.println(arequalbythreedecimalplaces(3.174D,3.175D))给出的值发送的第二组值发生意外行为。对于
double
variable
d
来说,输出应该与
float
variable
f
的输出一样,但是
Math.floor(d)
返回
0.000000
我期望的
1.000000
用以下内容替换上一次打印的语句:

double: 0.000000  float: 0.000000
d: 0.900000       f: 0.900000
true
double: 0.000000  float: 1.000000
d: 1.000000       f: 1.000000
false
double: 0.000000  float: 0.000000
d: 0.000000       f: 0.000000
true

Process finished with exit code 0
这会打印带有更多小数位的数字。然后您可以看到
d
实际上小于
1
。这是因为浮点数(如双精度或浮点)通常不能准确表示十进制值


这是因为浮点数在内部表示为二进制值(基数2)。所以在十进制表示法中,1/5正好是0.2,但在以2为底的表示法中,它是一个无限浮点数,就像十进制表示法中的1/3是0.333

请包括您期望的输出和您得到的。浮点和双精度只能近似表示小数。根据舍入效应,差异可能高于或低于预期。您的特定测试(等于小数点后三位)定义不清,使用二进制浮点算法没有合适的解决方案。最好打印
新的BigDecimal(d)
,而不是
d
,以获得精确的十进制值<代码>%2.15f
可能不是全部事实。我对这里的最后一句话有点不舒服-浮点数是精确的值,它们不一定是以前操作的精确结果。例如,如果一个浮点类型有两个十进制数字,并试图表示1/3,则结果将正好是0.33,但这并不完全是“三分之一”。这是近似运算,而不是值本身。@Roland Illig,是的
%2.15f
可能不是全部真理,但它在这里足以说明问题的原因。
%2.15f
在这里只是巧合而已。由于舍入误差,它也可能导致错误的方向,这正是导致这个问题的原因。因此,这是一个糟糕的建议,因为它在类似情况下不能可靠地工作。为了给出有用的答案并获得选票,你应该写出在所有情况下都适用的答案,并提高提问者的知识水平。
double: 0.000000  float: 0.000000
d: 0.900000       f: 0.900000
true
double: 0.000000  float: 1.000000
d: 1.000000       f: 1.000000
false
double: 0.000000  float: 0.000000
d: 0.000000       f: 0.000000
true

Process finished with exit code 0
System.out.println(String.format("double: %2.15f  float: %f%nd: %2.15f\t\t  f: %f", Math.floor(d), Math.floor(f), d, f));