4

this code gives me an error at the line I have mentioned setScale(); It gives me an error saying Rounding Necessary. I am trying to make an app which will take in cp and sp and then find the profit/loss percentage according to the profit/loss. Could someone please help me with the BigDecimal statement?

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

abstract class functions
{
    abstract void cpSP();
}

public class Percentage
{
    static Scanner sc = new Scanner(System.in);
    public void cpSP()
    {
        System.out.println("Enter the Cost Price:");
        double CP = sc.nextDouble();
        System.out.println("Enter the Selling Price:");
        double SP = sc.nextDouble();
        if (CP > SP)
        {
            System.out.println("As the Cost Price is greater than the Selling Price, there will be LOSS.");
            System.out.println("Loss = CP - SP");
            double loss = CP - SP;
            System.out.println("Loss = " + loss);
            System.out.println("Now,");
            System.out.println("Loss percentage = Loss/CP x 100");
            System.out.println("");
            double lossPercentage = (loss/CP)*100;
            String lPString = Double.toString(lossPercentage);
            BigDecimal bd = new BigDecimal(lPString);
            bd.setScale(2);
            System.out.println("Loss percentage = " + bd + "%" );
        }
        else if (SP > CP) 
        {
            System.out.println("As the Cost Price is less than the Selling Price, there will be PROFIT.");
            System.out.println("Profit = SP - CP");
            double profit = SP - CP;
            System.out.println("Profit = " + profit);
            System.out.println("Now,");
            System.out.println("Profit percentage = Profit/CP x 100");
            double profitPercentage = (profit / CP)*100;
            String pPString = Double.toString(profitPercentage);
            BigDecimal bd = new BigDecimal(pPString).setScale(2, RoundingMode.UNNECESSARY);
            System.out.println("Proft percentage = " + bd + "%" );
        }
        else
        {
            System.out.println("No profit, no loss.");
        }
    }


    public static void main(String[] args)
    {
        Percentage p = new Percentage();
        System.out.println("Select an option:");
        System.out.println("1. Find profit/loss percentage where the CP and SP is given.");
        int select = sc.nextInt();

        if (select == 1)
        {
           p.cpSP(); 
        }
    }

}
```

The error is:

Exception in thread "main" java.lang.ArithmeticException: Rounding necessary
    at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148)
    at java.math.BigDecimal.needIncrement(BigDecimal.java:4204)
    at java.math.BigDecimal.divideAndRound(BigDecimal.java:4112)
    at java.math.BigDecimal.setScale(BigDecimal.java:2452)
    at java.math.BigDecimal.setScale(BigDecimal.java:2386)
    at maths.Percentage.cpSP(Percentage.java:45)
    at maths.Percentage.main(Percentage.java:64)
arujbansal
  • 117
  • 2
  • 12
  • Can you post the exact error – Thiyagu Jul 04 '18 at 11:35
  • Exception in thread "main" java.lang.ArithmeticException: Rounding necessary at java.math.BigDecimal.commonNeedIncrement(BigDecimal.java:4148) at java.math.BigDecimal.needIncrement(BigDecimal.java:4204) at java.math.BigDecimal.divideAndRound(BigDecimal.java:4112) at java.math.BigDecimal.setScale(BigDecimal.java:2452) at java.math.BigDecimal.setScale(BigDecimal.java:2386) at maths.Percentage.cpSP(Percentage.java:45) at maths.Percentage.main(Percentage.java:64) – arujbansal Jul 04 '18 at 11:36

1 Answers1

6

It is clearly mentioned in the javadoc of the setScale method

@throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY} and the specified scaling operation would require rounding.

Example: This would throw the above exception

new BigDecimal("1200.1234").setScale(2, BigDecimal.ROUND_UNNECESSARY)

Because when you reduce it's scale to 2 you need to specify how to round it - round up (1200.13) or round down (1200.12)

If you need two decimal places only, choose a rounding mode (whichever is acceptable to you)

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
  • So what should I do to get upto 2 decimal places for the percentage? – arujbansal Jul 04 '18 at 11:44
  • Just choose a rounding mode (whichever is acceptable to you) – Thiyagu Jul 04 '18 at 11:46
  • Thanks a lot, it is now working. I was having some trouble with the docs – arujbansal Jul 04 '18 at 11:47
  • This is the correct answer but I suggest you to avoid the double for this reason https://stackoverflow.com/questions/322749/retain-precision-with-double-in-java. Read sc.nextBigDecimal and perform aritmethic with BigDecimal – Aris2World Jul 04 '18 at 11:52