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

13 java rounding

Math.rint()和之间有什么区别Math.round()

Tim*_*sen 15

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));
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这里一个重要的注意事项是.rint()并没有普遍向下舍入.它实际上舍入到.5边界上最近的偶数整数.如果您使用Math.rint(1.5),它实际上会向上舍入到2.0. (5认同)
  • 谢谢@Fleep。总结一下:*此方法对称地处理正值和负值,因此没有符号偏差*。 (3认同)
  • @Matthieu 参见 https://en.wikipedia.org/wiki/Rounding#Round_half_to_even (2认同)

小智 7

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


Lau*_*rel 4

.5当传递以、符号 0、NaN 或 Infinity结尾的内容时,它们的行为会有所不同。

Math.round接受doubles 和floats,并且由于某种原因具有不同的返回类型(long分别int是足以覆盖参数表示的整个范围的最小类型)。

Math.rint接受doubles 并返回doubles。它的“破坏性”较小,Math.round因为它在多种条件下不会改变值(见下文)。

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

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


来自文档

static double rint(double a)
Run Code Online (Sandbox Code Playgroud)

返回值最接近参数且等于数学整数的双精度值。

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

特别案例:

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

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

...

static long round(double a)
Run Code Online (Sandbox Code Playgroud)

...

static int round(float a)
Run Code Online (Sandbox Code Playgroud)

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

特别案例:

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

Math.round您还可以通过RoundingMode更改行为:

public enum RoundingMode
extends Enum<RoundingMode>
Run Code Online (Sandbox Code Playgroud)

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

每个舍入模式描述都包括一个表格,列出了在所讨论的舍入模式下不同的两位小数值如何舍入为一位小数值。表中的结果列可以通过以下方式获得:创建具有指定值的 BigDecimal 数字,形成具有正确设置的 MathContext 对象(精度设置为 1,roundingMode 设置为相关舍入模式),然后在此调用 round具有适当 MathContext 的数字。下面显示了显示所有舍入模式的舍入操作结果的汇总表。

使用给定舍入将输入舍入到一位数字的结果

输入 向上 向下 天花板 地面 半上 半下 HALF_EVEN 不必要
5.5 6 5 6 5 6 5 6 抛出算术异常
2.5 3 2 3 2 3 2 2 抛出算术异常
1.6 2 1 2 1 2 2 2 抛出算术异常
1.1 2 1 2 1 1 1 1 抛出算术异常
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 抛出算术异常
-1.6 -2 -1 -1 -2 -2 -2 -2 抛出算术异常
-2.5 -3 -2 -2 -3 -3 -2 -2 抛出算术异常
-5.5 -6 -5 -5 -6 -6 -5 -6 抛出算术异常