簡體   English   中英

使用java.math.MathContext

[英]Use of java.math.MathContext

最近我嘗試了解java.math.MathContext的使用但未能正確理解。 它是否用於java.math.BigDecimal舍入。 如果是,為什么不繞十進制數字,甚至是尾數部分。

從API文檔中,我發現它遵循ANSI X3.274-1996ANSI X3.274-1996/AM 1-2000 ANSI X3.274-1996規范中指定的標准,但我沒有讓它們在線閱讀。

如果您對此有任何想法,請告訴我。

要僅舍入BigDecimal的小數部分,請查看BigDecimal.setScale(int newScale, int roundingMode)方法。

例如,將小數點后的三位數字更改為兩位數的數字,並向上舍入:

BigDecimal original = new BigDecimal("1.235");
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP);

結果是BigDecimal值為1.24(因為舍入規則)

@jatan

謝謝你的回答。 這說得通。 你能否在BigDecimal#round方法的上下文中解釋我的MathContext。

BigDecimal.round() 任何其他BigDecimal方法沒有什么特別之處。 在所有情況下, MathContext指定有效位數和舍入技術。 基本上,每個MathContext都有兩個部分。 有一個精度,還有一個RoundingMode

精度再次指定有效位數。 因此,如果您將123指定為數字,並要求2位有效數字,那么您將獲得120 如果從科學記數的角度思考,可能會更清楚。

科學記數法中1231.23e2 如果您只保留2位有效數字,那么您將獲得1.2e2120 通過減少有效位數,我們降低了指定數字的精度。

RoundingMode部分指定了我們應該如何處理精度損失。 要重復使用該示例,如果使用123作為數字,並要求2位有效數字,則會降低精度。 使用RoundingModeHALF_UP (默認模式), 123將變為120 使用CEILINGRoundingMode ,你將得到130

例如:

System.out.println(new BigDecimal("123.4",
                   new MathContext(4,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.CEILING)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(1,RoundingMode.CEILING)));

輸出:

123.4
1.2E+2
1.3E+2
2E+2

您可以看到精度和舍入模式都會影響輸出。

我想在這里添加一些例子。 我沒有在之前的答案中找到它們,但我發現它們對於那些可能誤導有效 小數 位數的人有用。 我們假設,我們有這樣的背景:

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP);

對於此代碼:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX);
System.out.println(d1);

很明顯,你的結果是1.23E+3 ,如上所述。 首字母是123 ...

但在這種情況下:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX);
System.out.println(d2);

你的號碼在逗號后不會四舍五入 - 對某些人來說,這可能不直觀,值得強調。 相反,它將四舍五入到前3位有效數字 ,在本例中為“4 5 4”。 所以上面的代碼導致4.55E-7而不是0.000正如有人所期望的那樣。

類似的例子:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX);
 System.out.println(d3);  // 0.00100

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX);
 System.out.println(d4);   // 0.200

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX);
    System.out.println(d5); //4.00E-9

我希望這顯而易見,但相關的例子會有所幫助......

如果我正確理解你,聽起來好像你期望MathContext控制小數點后應該保留多少位數。 這不是它的用途。 它指定要保留的位數, 總數 因此,如果您指定需要3位有效數字,那就是您要獲得的所有數字。

例如,這個:

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(20)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(10)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(5)));

將輸出:

1234567890.123456789
1234567890
1.2346E+9

這不是為了好玩。 實際上我找到了一些在線示例,其中說明了使用MathContext來舍入存儲在BigDecimal中的金額/數字。

例如,

如果MathContext配置為具有precision = 2rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294舍入0.53

所以我認為這是一種更新的技術並用它來進行舍入。 然而它變成了噩夢,因為它甚至開始繞過數字的一部分。

例如,

Number = 1.5294舍入為1.5

Number = 10.5294舍入為10

Number = 101.5294舍入為100

.... 等等

所以這不是我期望的舍入行為(因為精度= 2)。

它似乎有一些邏輯,因為從模式我可以說它需要數字的前兩位(精度是2)然后追加0直到no。 數字與未包含的數量相同(結帳101.5294的例子...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM