ArithmeticException: “Non-terminating decimal expa

2019-01-01 09:41发布

Why does the following code raise the exception shown below?

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.

9条回答
看淡一切
2楼-- · 2019-01-01 10:17

It´s a issue of rounding the result, the solution for me is the following.

divider.divide(dividend,RoundingMode.HALF_UP);
查看更多
旧人旧事旧时光
3楼-- · 2019-01-01 10:18

For fixing such an issue I have used below code

a.divide(b, 2, RoundingMode.HALF_EVEN)

2 is precision. Now problem was resolved.

查看更多
泛滥B
4楼-- · 2019-01-01 10:19

From the Java 8 docs:

When a MathContext object is supplied with a precision setting of 0 (for example, MathContext.UNLIMITED), arithmetic operations are exact, as are the arithmetic methods which take no MathContext object. (This is the only behavior that was supported in releases prior to 5.)

As a corollary of computing the exact result, the rounding mode setting of a MathContext object with a precision setting of 0 is not used and thus irrelevant. In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3.

If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.

To fix, you need to do something like this:

a.divide(b, 2, RoundingMode.HALF_UP)

where 2 is precision and RoundingMode.HALF_UP is rounding mode

More details: http://jaydeepm.wordpress.com/2009/06/04/bigdecimal-and-non-terminating-decimal-expansion-error/

查看更多
残风、尘缘若梦
5楼-- · 2019-01-01 10:19

Answer for BigDecimal throws 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")));
    }

Add MathContext object in your divide method call and adjust precision and rounding mode. This should fix your problem

查看更多
素衣白纱
6楼-- · 2019-01-01 10:21

I had this same problem, because my line of code was:

txtTotalInvoice.setText(var1.divide(var2).doubleValue() + "");

I change to this, reading previous Answer, because I was not writing decimal precision:

txtTotalInvoice.setText(var1.divide(var2,4, RoundingMode.HALF_UP).doubleValue() + "");

4 is Decimal Precion

AND RoundingMode are Enum constants, you could choose any of this UP, DOWN, CEILING, FLOOR, HALF_DOWN, HALF_EVEN, HALF_UP

In this Case HALF_UP, will have this result:

2.4 = 2   
2.5 = 3   
2.7 = 3

You can check the RoundingMode information here: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

查看更多
回忆,回不去的记忆
7楼-- · 2019-01-01 10:28

You can do

a.divide(b, MathContext.DECIMAL128)

You can choose the number of bits you want either 32,64,128.

Check out this link :

http://edelstein.pebbles.cs.cmu.edu/jadeite/main.php?api=java6&state=class&package=java.math&class=MathContext

查看更多
登录 后发表回答