簡體   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