为什么Math.ceil返回一个double类型的值?

82
当我调用Math.ceil(5.2)时,返回的是double类型的6.0。我的自然倾向是认为Math.ceil(double a)会返回一个long类型的值。但从文档上看:

ceil(double a)

返回不小于参数的最小(接近负无穷大)double值,且等于某个数学整数。

为什么返回一个double而不是long呢?即使结果是整数?我认为理解其背后的原因可能有助于我更好地理解Java。同时也可能有助于我弄清楚是否将其转换为long类型会出现问题,例如:

long b = (long)Math.ceil(a);

是否总是得到我所期望的结果?我担心会有一些边界情况出现问题。

请查看此链接:https://dev59.com/C3A75IYBdhLWcg3wOWRd - starblue
2个回答

74

double类型的范围比long类型大。例如:

double x = Long.MAX_VALUE;
x = x * 1000;
x = Math.ceil(x);

如果 Math.ceil 返回 long,那么你会预期最后一行代码会做什么?

请注意,在非常大的值(正数或负数)的情况下,数字分布得非常稀疏 - 因此,比整数 x 大的下一个整数将不会是 x + 1,如果你能明白我的意思。


1
我猜在你的最后一句话中,你谈论的是精度损失,但我认为这并不取决于数字有多大,而是取决于它的有效数字位数(以二进制表示)。我会尝试找一个例子。 - aalku
@user270349:随着值的增大,连续双精度值之间的绝对差变得更大。表示的有效数字数量保持不变(除了次正常数)。 - Jon Skeet
2
2^60 可以表示为双精度浮点数,而 2^60 (+/-) 1 则不能。 - aalku
你是对的。如果指数很大,那么尾数增加一意味着一个更大的数字,这是显而易见的。 - aalku
10
那么为什么round返回一个long呢? - Zoltán
1
Zoltán,没错。Math.round返回long与上述推理不一致。 - Tim Harper

14

一个双精度浮点数(double)可能比 Long.MAX_VALUE 还要大。如果你在这样的值上调用 Math.ceil() 方法,你期望会返回相同的值。然而,如果它返回一个长整型(long),那么这个值就不正确了。


double类型的值如果大于Long.MAX_VALUE可能无法准确表示,因此ceil(big_double)double结果将不会是big_double + 1。因此仍然是不正确的... - Ciprian Tomoiagă
@CiprianTomoiaga,你说得对,它不会是big_double +1,因为这将是big_double。任何太大而无法表示为“long”的值都没有小数部分。 - Peter Lawrey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接