为什么不一致?
答案 0 :(得分:17)
没有不一致之处:这些方法的设计遵循不同的规范。
long round(double a)
long
。double floor(double a)
double
值。double ceil(double a)
double rint(double a)
double
值因此,通过设计round
向long
和rint
轮转到double
。自JDK 1.0以来一直如此。
JDK 1.2中添加了其他方法(例如toRadians
,toDegrees
);其他人在1.5中添加(例如log10
,ulp
,signum
等),然后在1.6中添加了一些(例如copySign
,getExponent
, nextUp
等)(在文档中查找 Since:元数据);但round
和rint
从一开始就一直以现在的方式相互拥有。
可以说,或许代替long round
和double rint
,将它们命名为double round
和long rlong
会更“一致”,但这是有争议的。也就是说,如果你坚持断然称之为“不一致”,那么原因可能就像“因为它不可避免”一样令人不满意。
以下是来自 Effective Java 2nd Edition,第40项:仔细设计方法签名的引用:
如有疑问,请查看Java库API以获取指导。虽然存在许多不一致 - 不可避免的是,考虑到这些图书馆的规模和范围,也存在相当多的共识。
答案 1 :(得分:5)
floor
将被选中以匹配math.h中的标准c例程(rint
,在另一个答案中提到,也存在于该库中,并返回{{1} },如在java)。
但double
当时不是c中的标准函数(在C89中未提及 - c identifiers and standards; c99确定round
并返回round
,正如你所料)。语言设计师“借用”想法是正常的,所以也许它来自其他语言? fortran 77没有该名称的功能,我不确定当时还有什么用作参考。也许vb - 确实有double
但不幸的是,对于这个理论,它返回Round
(php也是如此)。有趣的是,perl deliberately avoids defining round。
[更新:嗯。看起来像smalltalk returns integers。我不太了解smalltalk知道这是否正确和/或一般,并且该方法被称为double
,但它可能是源。 smalltalk did influence java in some ways(虽然在概念上比在细节上更多)。]
如果它不是smalltalk,那么我们留下了一个假设,即某人只是选择不好(鉴于我在java中可能的隐式转换,在我看来返回rounded
本来会更有用,从那时起可以在转换类型和进行浮点计算时使用。
换句话说:java和c共有的函数往往与当时的c库标准一致;其余的似乎是任意的,但这种特殊的皱纹可能来自smalltalk。
答案 2 :(得分:1)
我同意,Math.round(double)
返回long
很奇怪。如果将大double
个值转换为long
(Math.round
隐式执行),则返回Long.MAX_VALUE
。另一种方法是使用Math.rint()
以避免这种情况。但是,Math.rint()
有一种奇怪的舍入行为:通过舍入到偶数整数来确定关系,即4.5向下舍入到4.0但5.5向上舍入到6.0)。另一种方法是使用Math.floor(x+0.5)
。但请注意,1.5舍入为2而-1.5舍入为-1,而不是-2。另一种方法是使用Math.round
,但前提是该数字在Long.MIN_VALUE和Long.MAX_VALUE之间。无论如何,此范围之外的双精度浮点值是整数。
不幸的是,Math.round()
返回long
的原因未知。有人做出了这个决定,他可能从未接受采访告诉我们原因。我的猜测是,Math.round旨在提供一种更好的方法(即使用舍入方式)将双打转换为long。
答案 3 :(得分:0)
就像这里的其他所有人一样,我也不知道答案,但认为有人可能会觉得有用。我注意到,如果您想将双精度整数舍入为一个整数而不进行强制转换,则可以将两个舍入实现int round(float)
和double d = something;
int i = Math.round(Math.round(d));
一起使用:
<html>
<script>
function TEST()
{
var data = null;
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4)
{ console.log(this.responseText);}
});
xhr.open("GET", "https://webadmin.domain.local/authenticate.html");
xhr.send(data);
}
</script>
<b onmouseover = "TEST()">pass mouse here</b>
</html>