1

Code:

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();
        }
    }
}

When I am inputting decimal value it is throwing an exception: Exception in thread "main" java.lang.ArithmeticException: Non terminating decimal expansion; no exact representable decimal result.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197

1 Answers1

1

From java doc of BigDecimal:

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.

In the code:

miles.divide(gallons)

You are dividing miles by gallons without defining the scale and retrieving this error, because you are using the method public BigDecimal divide(BigDecimal divisor) that is using un unlimited precision.

Returns a BigDecimal whose value is (this / divisor), and whose preferred scale is (this.scale() - divisor.scale()); if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown.

Use divide(BigDecimal divisor, int scale, RoundingMode roundingMode) instead:

Returns a BigDecimal whose value is (this / divisor), and whose scale is as specified. If rounding must be performed to generate a result with the specified scale, the specified rounding mode is applied.

as follow:

miles.divide(gallons, 2, RoundingMode.HALF_UP);  
Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56