-1

I have a GUI which works like the following: there are 2 buttons and 1 textField. The textField is used to hold double/float values, 1 of the buttons adds a value (in this case, 0.1) and the other one subtracts (adds -0.1).

Here is my following problem: after pressing one of the buttons many times, the resulting value is not behaving the way I would like. In other words, instead of "1.5" turning into "1.6", it will be something like "1.5999998". I have tried many changes (like changing the variables types and the value to add/subtract), but none of these worked. Here's a piece of my code:

public void sumTextField(){
    try{
        if(textField.getText() == "")
            textField.setText("0.1");
        else{
            float aux = Float.parseFloat(textField.getText());
            aux += 0.10000000;
            textField.setText(String.valueOf(aux));
            }   
        }
    catch(NumberFormatException nfe){
       nfe.printStackTrace();
       JOptionPane.showMessageDialog(null, "Please, provide a valid value in the text field!", "Impossible sum", JOptionPane.INFORMATION_MESSAGE);
     }
}

public void subtractTextField(){
    try{
        if(textField.getText() == "")
            textField.setText("-0.1");
        else{
            float aux = Float.parseFloat(textField.getText());
            aux -= 0.10000000;
            textField.setText(String.valueOf(aux));
            }   
        }
    catch(NumberFormatException nfe){
       nfe.printStackTrace();
       JOptionPane.showMessageDialog(null, "Please, provide a valid value in the text field!", "Impossible subtraction", JOptionPane.INFORMATION_MESSAGE);
     }
}

Any ideas are welcome

Mudkip
  • 373
  • 6
  • 27
  • 9
    First thing to fix - stop using `==` to compare strings (http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java) – Jon Skeet Aug 05 '14 at 10:39
  • See - http://stackoverflow.com/questions/327544/strange-floating-point-behaviour-in-a-java-program?rq=1 – codelion Aug 05 '14 at 10:39
  • 6
    Next, you should probably read more about binary floating point, and consider using `BigDecimal` instead. – Jon Skeet Aug 05 '14 at 10:39
  • ++ both comment from Jon Skeet, after Jon there's nothing left :( – aviad Aug 05 '14 at 10:40
  • @JonSkeet in this case, a call to `isEmpty()` would be more appropriate than `equals("")`. – bcsb1001 Aug 05 '14 at 10:46
  • @bcsb1001: Maybe - either way would be *correct*, which is a lot more than can be said for the current approach. – Jon Skeet Aug 05 '14 at 10:47

1 Answers1

2

Your problem is due to the way in which double and float work.

In floating-point arithmetic, the computer only calculates to a certain precision, i.e. after so many decimal places, it just rounds the number off. 0.1 may seem like a nice round number in decimal, but in binary it is recurring - 0.0001100110011 and so on. With each calculation, the rounding-off makes the result a bit more inaccurate. Have a look at this page for a more thorough explanation.

double is more precise than float, but it will still display rounding errors like this.

To circumvent the problem, you could do one of two things. First, as Jon Skeet said in the comments, you could use arbitrary-precision arithmetic like BigDecimal.

Alternatively, you could print out only a couple of decimal places like this:

String answer = String.format("%.2f", myNumber);

This will round off the printed value to 2 decimal places.

Hope this helps!

Eoin
  • 833
  • 2
  • 13
  • 24