![](/img/trans.png)
[英]Java run-time error “ Non-terminating decimal expansion; no exact representable decimal result” in BigDecimal class
[英]ArithmeticException: “Non-terminating decimal expansion; no exact representable decimal result”
為什么以下代碼會引發如下所示的異常?
BigDecimal a = new BigDecimal("1.6");
BigDecimal b = new BigDecimal("9.2");
a.divide(b) // results in the following exception.
例外:
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
當
MathContext
對象的精度設置為 0(例如MathContext.UNLIMITED
)時,算術運算是精確的,不采用MathContext
對象的算術方法也是如此。 (這是 5 之前的版本中唯一支持的行為。)作為計算精確結果的必然結果,精度設置為 0 的
MathContext
對象的舍入模式設置未使用,因此無關緊要。 在除法的情況下,精確的商可以有無限長的十進制展開; 例如,1 除以 3。如果商具有非終止的十進制擴展並且指定操作返回精確結果,則拋出
ArithmeticException
。 否則,將返回除法的確切結果,就像其他操作一樣。
要修復,您需要執行以下操作:
a.divide(b, 2, RoundingMode.HALF_UP)
其中 2 是比例和 RoundingMode.HALF_UP 是舍入模式
有關更多詳細信息,請參閱此博客文章。
因為您沒有指定精度和舍入模式。 BigDecimal 抱怨它可以使用 10、20、5000 或無窮大小數位,但它仍然無法為您提供數字的精確表示。 因此,它不會為您提供不正確的 BigDecimal,而是只會對您發牢騷。
但是,如果您提供 RoundingMode 和精度,那么它將能夠轉換(例如 1.333333333 到無窮大到 1.3333 之類的東西……但是作為程序員,您需要告訴它您對什么精度感到滿意'。
你可以做
a.divide(b, MathContext.DECIMAL128)
您可以選擇所需的位數為 32、64、128。
查看此鏈接:
為了解決這樣的問題,我使用了下面的代碼
a.divide(b, 2, RoundingMode.HALF_EVEN)
二是精准。 現在問題解決了。
我有同樣的問題,因為我的代碼行是:
txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");
我改為這個,閱讀以前的答案,因為我沒有寫小數精度:
txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");
4 是十進制精度
AND RoundingMode 是 Enum 常量,你可以選擇UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP
在這種情況下 HALF_UP,將有這樣的結果:
2.4 = 2
2.5 = 3
2.7 = 3
您可以在此處查看RoundingMode
信息: http : //www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/
這是一個舍入結果的問題,我的解決方案如下。
divider.divide(dividend,RoundingMode.HALF_UP);
BigDecimal 的答案拋出 ArithmeticException
public static void main(String[] args) {
int age = 30;
BigDecimal retireMentFund = new BigDecimal("10000.00");
retireMentFund.setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal yearsInRetirement = new BigDecimal("20.00");
String name = " Dennis";
for ( int i = age; i <=65; i++){
recalculate(retireMentFund,new BigDecimal("0.10"));
}
BigDecimal monthlyPension = retireMentFund.divide(
yearsInRetirement.divide(new BigDecimal("12"), new MathContext(2, RoundingMode.CEILING)), new MathContext(2, RoundingMode.CEILING));
System.out.println(name+ " will have £" + monthlyPension +" per month for retirement");
}
public static void recalculate (BigDecimal fundAmount, BigDecimal rate){
fundAmount.multiply(rate.add(new BigDecimal("1.00")));
}
在您的除法調用中添加 MathContext 對象並調整精度和舍入模式。 這應該可以解決您的問題
您的程序不知道要使用的十進制數的精度是多少,因此它會拋出:
java.lang.ArithmeticException: Non-terminating decimal expansion
MathContext precision = new MathContext(int setPrecisionYouWant); // example 2
BigDecimal a = new BigDecimal("1.6",precision);
BigDecimal b = new BigDecimal("9.2",precision);
a.divide(b) // result = 0.17
這是因為Bigdecimal不會丟失,例如,如果將1/3除,則將導致重復的十進制到無窮大。 0.33333333 ...從理論上講,如果再相乘,您將得到准確的結果。 但是,無窮大數將生成堆棧溢出,在這種情況下,將引發異常。
一個辦法:
try {
result = n1.divide(n2);
} catch (ArithmeticException e){
Log.d("Error bigdecimal", e.toString());
result = (n1.doubleValue() / n2.doubleValue());
};
要么
n1.divide(n2,RoundingMode.HALF_UP);
在這種情況下,您的結果將不會被舍入
對我來說,它正在處理這個:
BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);
a.divideToIntegralValue(b).setScale(2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.