繁体   English   中英

Java中Math.rint()和Math.round()之间的区别

[英]Difference between Math.rint() and Math.round() in Java

Math.rint()Math.round()什么区别?

Math.rint()Math.round()有几个不同之处,但是可能影响Java应用程序的业务逻辑的是它们处理边界上的整数舍入的方式(例如4.5在边界上) 45 )。 请考虑以下代码段和输出:

double val1 = 4.2;
double val2 = 4.5;
System.out.println("Math.rint(" + val1 + ")    = " + Math.rint(val1));
System.out.println("Math.round(" + val1 + ")   = " + Math.round(val1));
System.out.println("Math.rint(" + val2 + ")    = " + Math.rint(val2));
System.out.println("Math.round(" + val2 + ")   = " + Math.round(val2));
System.out.println("Math.rint(" + (val2 + 0.001d) + ")  = " + Math.rint(val2 + 0.001d));
System.out.println("Math.round(" + (val2 + 0.001d) + ") = " + Math.round(val2 + 0.001d));

输出:

Math.rint(4.2)    = 4.0
Math.round(4.2)   = 4
Math.rint(4.5)    = 4.0
Math.round(4.5)   = 5
Math.rint(4.501)  = 5.0
Math.round(4.501) = 5

正如您所看到的, Math.rint(4.5)实际上是向下Math.rint(4.5) ,而Math.round(4.5)向上Math.rint(4.5) ,这值得指出。 但是,在所有其他情况下,它们都表现出我们期望的相同的舍入规则。

这是一篇有用的Code Ranch文章,简要比较了Math.rint()Math.round()http//www.coderanch.com/t/239803/java-programmer-OCPJP/certification/Difference-rint-methods-数学课

Math.rint()的示例: 2.50位于2.00和3.00之间。 Math.rint()返回最接近的偶数double值。 Math.rint(2.50)返回2.0。

Math.round()的示例: 2.50介于2.00和3.00之间。 Math.round()返回最接近的较高整数。 Math.round(2.50)返回3

差异在.5

Math.round()[10.5, 11.5[ Math.round() [10.5, 11.5[转换为11]
Math.rint()转换]10.5, 11.5[ Math.rint() ]10.5, 11.5[到11.0

Math.round()返回long或int。
Math.rint()返回double。

因此,可以说Math.round()倾向于使用中点(0.5)来获得更高的值。

有一种类型返回差异:

Math.round()返回longint
Math.rint()返回double

但关键的区别在于0.5的数值处理。

Math.round()9.5 <= x < 10.5转换为10
Math.rint()9.5 <= x <= 10.510.0

Math.round()10.5 <= x < 11.5转换为11
Math.rint()10.5 < x < 11.5转换为11.0

Math.round()11.5 <= x < 12.5转换为12
Math.rint()11.5 <= x <= 12.512.0

(注意不等式!)所以Math.round()总是在中间点(0.5): 文档
相反, Math.rint()倾向于在中间点使用最接近的偶数: 文档

例如,尝试运行以下简单示例:

public class HelloWorld{
    public static void main(String []args){
        System.out.println("Math.round() of 9.5 is " + Math.round(9.5));
        System.out.println("Math.round() of 10.5 is " + Math.round(10.5));
        System.out.println("Math.round() of 11.5 is " + Math.round(11.5));
        System.out.println("Math.round() of 12.5 is " + Math.round(12.5));
        System.out.println("Math.rint() of 9.5 is " + Math.rint(9.5));
        System.out.println("Math.rint() of 10.5 is " + Math.rint(10.5));
        System.out.println("Math.rint() of 11.5 is " + Math.rint(11.5));
        System.out.println("Math.rint() of 12.5 is " + Math.rint(12.5));
    }
}

请注意, 目前的最佳答案错误的 我尝试过对他的帖子进行编辑但是被拒绝了 因此,根据拒绝评论,我将我的编辑作为新答案。

当传递以.5 ,NaN或无穷大结尾的东西时,它们的行为会有所不同。

Math.round接受double s和float s,并且由于某种原因( longint分别具有不同的返回类型,它们是足以覆盖参数所代表的整个范围的最小类型)。

Math.rint接受double s并返回double s。 它比Math.round “破坏性”,因为它在几种情况下不会改变值(见下文)。

此方法的行为遵循IEEE标准754第4节。这种舍入有时称为舍入到最近,或者是银行家的舍入。 它最大限度地减少了在单个方向上始终舍入中点值所导致的舍入误差。

(来自Jon Skeet在C#中的回答。在C#中,Math.Round的行为更类似于Java的Math.rint ,因为它可能令人困惑。)


来自文档

 static double rint(double a) 

返回与参数值最接近的double值,它等于数学整数。

返回与参数值最接近的double值,它等于数学整数。 如果两个数学整数的double值同样接近,则结果是偶数的整数值。

特别案例:

  • 如果参数值已经等于数学整数,则结果与参数相同。

  • 如果参数为NaN或无穷大或正零或负零,则结果与参数相同。

...

 static long round(double a) 

...

 static int round(float a) 

返回与参数最接近的int,并将关系向上舍入。

特别案例:

  • 如果参数为NaN,则结果为0。
  • 如果参数为负无穷大或任何小于或等于Integer.MIN_VALUE值的值,则结果等于Integer.MIN_VALUE的值。
  • 如果参数为正无穷大或任何大于或等于Integer.MAX_VALUE值的值,则结果等于Integer.MAX_VALUE的值。

您还可以更改Math.round的行为。

 public enum RoundingMode extends Enum<RoundingMode> 

指定能够丢弃精度的数值运算的舍入行为。 每个舍入模式指示如何计算舍入结果的最低有效返回数字。 如果返回的数字少于表示精确数字结果所需的数字,则丢弃的数字将被称为丢弃的部分,而不管数字对数字值的贡献。 换句话说,被认为是数值,丢弃的部分可以具有大于1的绝对值。

每个舍入模式描述包括一个表,该表列出了在所讨论的舍入模式下不同的两位十进制值如何舍入到一位十进制值。 可以通过创建具有指定值的BigDecimal数字来获取表中的结果列,形成具有适当设置的MathContext对象(精度设置为1,并将roundingMode设置为所讨论的舍入模式),并在此上调用round使用正确的MathContext编号。 显示所有舍入模式的舍入操作结果的汇总表如下所示。

      |  Result of rounding input to one digit with the given rounding 
______ı________________________________________________________________________________________
      |
Input |   UP    DOWN   CEILING    FLOOR    HALF_UP    HALF_DOWN    HALF_EVEN    UNNECESSARY
 5.5  |   6      5        6         5         6           5            6        throw ArithmeticException
 2.5  |   3      2        3         2         3           2            2        throw ArithmeticException
 1.6  |   2      1        2         1         2           2            2        throw ArithmeticException
 1.1  |   2      1        2         1         1           1            1        throw ArithmeticException
 1.0  |   1      1        1         1         1           1            1         1
-1.0  |  -1     -1       -1        -1        -1          -1           -1        -1
-1.1  |  -2     -1       -1        -2        -1          -1           -1        throw ArithmeticException
-1.6  |  -2     -1       -1        -2        -2          -2           -2        throw ArithmeticException
-2.5  |  -3     -2       -2        -3        -3          -2           -2        throw ArithmeticException
-5.5  |  -6     -5       -5        -6        -6          -5           -6        throw ArithmeticException

对于正数:

如果小数部分位于0(包括)和0.5(不包括),则round()给出数字的整数部分。

如果小数部分位于0.5(包括)和1(不包括),则round()给出数字+ 1的整数部分。

但是在rint的情况下,

如果小数部分位于0(含)和0.5(含),则rint()给出数字的整数部分。

如果小数部分位于0.5(不包括)和1(不包括),则round()给出数字+ 1的整数部分。

对于负数:

两者都有相同的行为,即

如果小数部分位于0(含)和0.5(含)中,则返回数字的整数部分。

如果小数部分位于数字-1的0.5(包括)和1(不包括)整数部分中。

小数部分只是小数点后部分的一部分

由于你的问题得到了很大的回答,我不会忽略这些明显的观点,但会提供一篇我遇到的有用的文章:

https://way2java.com/java-lang/class-math-java-lang/difference-of-math-rintdouble-and-math-rounddouble/

我发现最重要的是round将最接近的较高 整数作为整数 整数返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM