计算MPG会导致java.lang.ArithmeticException:非终止的十进制扩展;没有确切可表示的十进制结果

时间:2018-12-18 15:33:17

标签: java

代码:

import java.util.Scanner;
import java.math.BigDecimal;
import java.math.RoundingMode;

public class MPGAppBigDecimal
{
    public static void main(String[] args)
    {
        System.out.println("Welcome to the Miles Per Gallon Calculator.");
        System.out.println();

        Scanner sc = new Scanner(System.in);
        String choice = "y";

        while (choice.equalsIgnoreCase("y"))
        {
            // get the miles driven from the user
            System.out.print("Enter miles driven: ");
            String milesString = sc.next();

            // get the gallons of gas used
            System.out.print("Enter gallons of gas used: ");
            String gallonsString = sc.next();

            // calculating miles per gallons
            BigDecimal miles = new BigDecimal(milesString);
            BigDecimal gallons = new BigDecimal(gallonsString);

            BigDecimal mpg = miles.divide(gallons).setScale(2, RoundingMode.HALF_UP);

            // display the result
            System.out.println("Miles per gallon is " + mpg.toString() + ".");
            System.out.println();

            // see if the user wants to continue
            System.out.print("Calculate another MPG? (y/n): ");
            choice = sc.next();
            System.out.println();
        }
    }
}

当我输入十进制值时,它将引发异常: 线程“主”中的异常java.lang.ArithmeticException:非终止的十进制扩展;没有精确的可表示的十进制结果。

1 个答案:

答案 0 :(得分:1)

摘自BigDecimal的Java文档:

  

为MathContext对象提供的精度设置为0(例如MathContext.UNLIMITED)时,算术运算是精确的,不采用MathContext对象的算术方法也是如此。 (这是5之前的发行版中唯一支持的行为。)作为计算精确结果的必然结果,没有使用精度设置为0的MathContext对象的舍入模式设置,因此是不相关的。在除法的情况下,精确的商可能具有无限长的十进制扩展;例如,1除以3。如果商具有不间断的十进制扩展数,并且指定了该操作以返回精确的结果,则抛出ArithmeticException。否则,将返回除法的精确结果,就像其他操作一样。

在代码中:

miles.divide(gallons)

由于您使用的方法public BigDecimal divide(BigDecimal divisor)使用的精度是无限的,因此您要用加仑除以加仑,而没有定义比例尺,也没有获取此错误。

  

返回一个BigDecimal,其值为(this / divisor),并且首选比例为(this.scale()-divisor.scale()); 如果无法表示确切的商(因为它具有无终止的十进制扩展名),则会引发ArithmeticException。

改为使用divide(BigDecimal divisor, int scale, RoundingMode roundingMode)

  

返回一个BigDecimal,其值为(this / divisor),并且其小数位数已指定。如果必须进行舍入以产生具有指定比例的结果,则将应用指定的舍入模式。

如下:

miles.divide(gallons, 2, RoundingMode.HALF_UP);