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

时间:2016-05-16 14:38:18

标签: java rounding

Math.rint()Math.round()之间的区别是什么?

7 个答案:

答案 0 :(得分:13)

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

5

<强>输出:

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)向上舍入,这值得指出。但是,在所有其他情况下,它们都表现出我们期望的相同的舍入规则。

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

答案 1 :(得分:6)

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

答案 2 :(得分:3)

差异在 .5

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

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

所以可以说Math.round()偏向中点(0.5)以获得更高的价值。

答案 3 :(得分:3)

存在类型返回差异:

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

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

Math.round()9.5 <= x < 10.5转换为10
Math.rint()9.5 <= x <= 10.5转换为10.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.5转换为12.0

(注意不平等!)所以Math.round()总是在中点(0.5)向上舍入:documentation
相反,Math.rint()支持中间点最近的偶数:documentation

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

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));
    }
}

请注意,the current top answer 错误。我尝试过对他的帖子进行编辑,但it was rejected。因此,根据拒绝评论,我将我的编辑作为新答案。

答案 4 :(得分:2)

当传递以.5,签名0,NaN或无穷大结尾的内容时,它们的行为会有所不同。

Math.round同时接受doublefloat s,并且由于某种原因(longint分别具有不同的返回类型,这些是最小的类型足够大以覆盖参数表示的整个范围。

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

  

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

(来自C#中的Jon Skeet's answer .C#中的Math.Round的行为与Java的Math.rint更相似,尽管可能会令人困惑。)

来自docs

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

答案 5 :(得分:1)

对于正数:

如果小数部分位于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(不包括)整数部分。

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

的一部分

答案 6 :(得分:0)

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

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

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