ArithmeticException:“非终止十进制扩展;没有精确可表示的十进制结果”

发布于 2024-10-10 12:58:03 字数 321 浏览 5 评论 0原文

为什么以下代码会引发如下所示的异常?

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.

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.

Exception:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

猫弦 2024-10-17 12:58:03

来自 Java 11 <代码>BigDecimal文档

MathContext 对象提供的精度设置为 0 时(例如,MathContext.UNLIMITED),算术运算是精确的,算术方法也是精确的不使用 MathContext 对象。 (这是 5 之前的版本中唯一支持的行为。)

作为计算精确结果的必然结果,精度设置为 0 的 MathContext 对象的舍入模式设置不会被使用,因此不相关。在除法的情况下,精确的商可以有无限长的小数展开式;例如,1 除以 3。

如果商具有不间断的小数扩展,并且指定运算返回精确结果,则会引发 ArithmeticException。否则,将返回除法的确切结果,就像其他操作一样。

要解决此问题,您需要执行以下操作

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

其中 2 是比例,RoundingMode.HALF_UP 是舍入模式

有关更多详细信息,请参阅 此博文

From the Java 11 BigDecimal 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 the scale and RoundingMode.HALF_UP is rounding mode

For more details see this blog post.

吻风 2024-10-17 12:58:03

因为您没有指定精度和舍入模式。 BigDecimal 抱怨它可以使用 10、20、5000 或无限小数位,但它仍然无法为您提供数字的精确表示。因此,它不会给你一个不正确的 BigDecimal,而是会抱怨你。

但是,如果您提供 RoundingMode 和精度,那么它将能够转换(例如 1.333333333-to-infinity 到 1.3333 之类的东西......但是您作为程序员需要告诉它您对什么精度感到满意'。

Because you're not specifying a precision and a rounding-mode. BigDecimal is complaining that it could use 10, 20, 5000, or infinity decimal places, and it still wouldn't be able to give you an exact representation of the number. So instead of giving you an incorrect BigDecimal, it just whinges at you.

However, if you supply a RoundingMode and a precision, then it will be able to convert (eg. 1.333333333-to-infinity to something like 1.3333 ... but you as the programmer need to tell it what precision you're 'happy with'.

入画浅相思 2024-10-17 12:58:03

您可以

a.divide(b, MathContext.DECIMAL128)

选择您想要的位数:32、64 或 128。

查看此链接:

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

You can do

a.divide(b, MathContext.DECIMAL128)

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

Check out this link :

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

旧话新听 2024-10-17 12:58:03

为了解决这个问题,我使用了下面的代码,

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

其中 2 是比例。现在问题应该解决了。

To fix such an issue I have used the below code

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

Where 2 is scale. Now the problem should be resolved.

丢了幸福的猪 2024-10-17 12:58:03

这是一个四舍五入结果的问题,我的解决方案如下。

divider.divide(dividend,RoundingMode.HALF_UP);

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

divider.divide(dividend,RoundingMode.HALF_UP);
过潦 2024-10-17 12:58:03

我遇到了同样的问题,因为我的代码行是:

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

我更改为这个,阅读之前的答案,因为我没有写十进制精度:

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

4是十进制精度

和RoundingMode是枚举常量,您可以选择其中任何一个
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-小数使用舍入模式枚举/

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 Precison

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/

陪你搞怪i 2024-10-17 12:58:03

回答 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")));
    }

在您的 除法调用中添加 MathContext 对象并调整精度和舍入模式。这应该可以解决你的问题

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

明月夜 2024-10-17 12:58:03

您的程序不知道要使用十进制数的精度,因此会抛出:

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

Your program does not know what precision for decimal numbers to use so it throws:

java.lang.ArithmeticException: Non-terminating decimal expansion

Solution to bypass exception:

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
仅一夜美梦 2024-10-17 12:58:03

对我来说,它正在与此一起工作:

BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);

a.divideToIntegralValue(b).setScale(2)

For me, it's working with this:

BigDecimal a = new BigDecimal("9999999999.6666",precision);
BigDecimal b = new BigDecimal("21",precision);

a.divideToIntegralValue(b).setScale(2)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文