-1

I am attempting to ask for a value and tax rate and multiple those together to get a amount owed. It works great if I use whole numbers but it will not work when using decimals.

package apples;
import javax.swing.JOptionPane;
class apples {

public static void main(String[] args) {
    String fn = JOptionPane.showInputDialog("Enter assessment value");
    String sn = JOptionPane.showInputDialog("Enter local tax rate");
    
    
    int num1 = Integer.parseInt(fn);
    int num2 = Integer.parseInt(sn);

    int sum = num1 * num2;
    
    JOptionPane.showMessageDialog(null, "Tax amount" +sum);

    
}

} I expected it to multiple .23 by the value entered but I get this.

Exception in thread "main" java.lang.NumberFormatException: For input string: ".23"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:654)
at java.base/java.lang.Integer.parseInt(Integer.java:786)
at apples.apples.main(apples.java:11)
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110

2 Answers2

1

The best data type to use for storing an amount of money is BigDecimal. It lets you do calculations with decimal amounts, without introducing floating point errors. It also keeps track of the precision of any number, which is useful for precise calculations.

If you try to use float or double instead of BigDecimal, small errors can creep into your calculations, which can cause problems when you try to compare values, or print values. There are some really good explanations of why this happens in the answers to this question so it's important to be aware of this.

You can easily change your code to use the BigDecimal class in place of Integer, except that you have to use methods (like add and multiply) instead of operators (like + and *). You might end up with something like this.

public static void main(String[] args) {
    String assessmentValueString = JOptionPane.showInputDialog("Enter assessment value");
    String taxRateString = JOptionPane.showInputDialog("Enter local tax rate");
    
    
    BigDecimal assessmentValue = new BigDecimal(assessmentValueString);
    BigDecimal taxRate = new BigDecimal(taxRateString);

    BigDecimal totalTax = assessmentValue.multiply(taxRate);
    
    JOptionPane.showMessageDialog(null, "Tax amount" + totalTax);
}

You may want the last calculation to be rounded to two decimal places, regardless of the amounts that are entered. You can do that like this.

    MathContext twoDecimals = new MathContext(2);
    BigDecimal totalTax = assessmentValue.multiply(taxRate, twoDecimals);
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
0

In your case, I would use a float since you don't want whole numbers but floating point numbers.
Instead of:

int num1 = Integer.parseInt(fn);

you would do:

float num1 = Float.parseFloat(fn);

So your sum variable also has to be a float. A float is just a float point number that has a precision of 6-7 decimals. Should be more than enough for tax rate.

arellak
  • 104
  • 2
  • 8
  • 3
    **Don't do this**. The `float` and `double` data types should generally not be used with money, because they introduce floating point errors that can lead to incorrect results. There are cases where it doesn't matter, but I don't think this is one of them. – Dawood ibn Kareem Jan 11 '23 at 02:53
  • I would say the exact opposite. It seems like OP is still learning, so it isn't production and therefore it's not necessary to bombard OP with datatypes like BigDecimal or whatever. You're talking about floating point errors, but which errors are you talking about? Only one comes to my mind and it only occurs in the last decimals where you have a deviation of 0.00001 or whatever – arellak Jan 11 '23 at 06:28
  • 1
    The fact that OP is still learning is a really good reason to give them a correct answer, not a wrong one. – Dawood ibn Kareem Jan 11 '23 at 08:17