为什么Math.floor返回双精度数?


103

官方Javadoc ,它Math.floor()返回的double“等于数学整数”,但是为什么它不返回一个int

Answers:


80

根据同一Javadoc:

如果自变量为NaN或无穷大或正零或负零,则结果与自变量相同。不能用int

最大的double价值也比最大的大int,所以它必须是一个long


40
似乎与Math.Round函数不一致,后者确实返回int / long并以不同方式处理特殊情况。
zod 2011年

1
请注意,Javadoc说它返回“最大(最接近正无穷大)*浮点值*,该小于或等于参数,并且等于一个数学整数”。给定x> 2 ^ 53的值,该值将与小数部分被截断的值不同。它可能比这要小得多。
吉姆·加里森

16

这是为了精确。double数据类型的尾数为53位。除其他外,这意味着双精度数最多可以表示2 ^ 53的所有整数而没有精度损失。

如果以整数存储这么大的数字,则会溢出。整数只有32位。

将整数返回为双精度是正确的做法,因为它提供了比整数更大的有用数字范围。


当然,要解决这些价值可能会很长。不过,您仍然必须计算出对Doubles> 2 ^ 63的处理方式。
Jon Skeet

1
@Jon,是的,但这会导致性能影响(在我所知道的任何指令集中,转换指令不会从长到两倍)。我想知道Math.floor首先如何处理双打> 2 ^ 53。有些结果无法代表。
Nils Pipenbrinck

但是,在正式的javadoc中也出现的伪惯用格式(int)Math.floor(foo)是不安全的,因为结果可能不适合int,是吗?然后再说一次,使用Math.floor是一种安全的形式,因为结果可能很长都不适合?
Raibaz

10

其他人已经告诉您原因,我将告诉您如何正确舍入。如果仅使用正数,则可以使用以下语句:

int a=(int) 1.5;

但是,(int)总是四舍五入。因此,如果要做一个负数:

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

就我而言,我不想这样做。我使用以下代码进行了四舍五入,似乎可以很好地处理所有边缘情况:

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

7
为什么不使用(int) Math.floor(a)?它可能更有效且更短。
所罗门·乌科

@aSolomon Ucko (int) Math.floor(a)可以简单地编写(int) a,如果a为正。
列奥·列昂捷夫

3

如果给它比最大int或double大一倍的值,您希望它返回什么?

(当然,如果大于最大长度,则精度仍然很低-可能不是最接近的理论整数-即便如此...)


0

就像Java中有整数和浮点除法一样,也有整数和浮点除法:

double f = Math.floor(x);

要么

int k = (int) x; 

但您始终需要谨慎使用有限精度算术的地板:您对x的计算可能会产生1.99999999之类的东西,它将两种形式都设置为1,而不是2。有许多算法需要解决此限制,以避免对某些输入值产生错误的结果。


0

这样,错误和其他非整数值可以通过一系列计算正确地级联。

例如,如果将“非数字(NaN)”输入到Math.floor中,它将传递它。

如果返回整数,则无法传递这些状态或错误,并且从较早的计算中可能会得到不好的结果,这些结果看起来不错,但在进一步处理后却出错了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.