Why does Math.floor return a double?

Official Javadoc says that Math.floor() returns a double that is "equal to a mathematical integer", but then why shouldn't it return an int?

56108 次浏览

According to the same Javadoc:

如果参数是 NaN或无穷大,或正负零,那么结果与参数相同。用 int可做不到。

最大的 double值也大于最大的 int,因此它必须是 long

这是为了精确度。双数据类型有一个53位尾数。除此之外,这意味着一个双精度数可以表示2 ^ 53的整数,而不会造成精度损失。

如果你在一个整数中存储如此大的数字,你会得到一个溢出。整数只有32位。

将整数作为双精度数返回是正确的,因为它提供了比整数更宽的有用数值范围。

因此,误差和其他非整数值可以正确级联通过一系列计算。

例如,如果您将 Not a Number (NaN)提供给 Math.floor,它将传递它。

如果它返回的是整数,那么它就无法传递这些状态或错误,并且您可能会从前面的计算中得到不好的结果,这些结果看起来不错,但是在进一步处理之后就出错了。

如果给它一个比最大的 int 或 long 大两倍的值,你希望它返回什么?

(Admittedly if it's bigger than the largest long the precision will be low anyway - it may not be the nearest theoretical integer - but even so...)

Just as there is an integer and a floating point division in Java, there are integer and floating point ways to do floor:

double f = Math.floor(x);

或者

int k = (int) x;

但是在使用有限精度算术的地板时,您总是需要小心: 您对 x 的计算可能会得到类似于1.99999999的结果,它将被两种形式的地板数都设置为1,而不是2。有许多算法需要绕过这个限制,以避免对某些输入值产生错误的结果。

其他人已经告诉了你为什么,我将告诉你如何正确地舍入,因为你想这样做。如果你只打算使用正数,那么你可以这样说:

int a=(int) 1.5;

然而,(int)总是向0舍入。因此,如果你想做一个负数:

int a=(int) -1.5; //Equal to -1

In my case, I didn't want to do this. I used the following code to do the rounding, and it seems to handle all of the edge cases well:

private static long floor(double a)
{
return (int) Math.floor(a);
}