为什么Math.round返回long但Math.floor返回double?

时间:2010-08-05 07:06:49

标签: java math

为什么不一致?

4 个答案:

答案 0 :(得分:17)

没有不一致之处:这些方法的设计遵循不同的规范。

因此,通过设计roundlongrint轮转到double。自JDK 1.0以来一直如此。

JDK 1.2中添加了其他方法(例如toRadianstoDegrees);其他人在1.5中添加(例如log10ulpsignum等),然后在1.6中添加了一些(例如copySigngetExponentnextUp等)(在文档中查找 Since:元数据);但roundrint从一开始就一直以现在的方式相互拥有。

可以说,或许代替long rounddouble rint,将它们命名为double roundlong 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个值转换为longMath.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>