0

I got a JSpinner with a step size of 0.01, but it seems, that the getValue() returns odd values.

As an example: its at 0.06 and if I increase that, it sometimes shows 0.06999999999999999 and not 0.07.

This kind of messes up some of my code, as I need to multiply that by 100 (0.069999999999 * 100 would be 6 and not 7!).

Any possible way to avoid that issue other than using Math.round for my multiplication?

spinnerU.setModel(new SpinnerNumberModel(0.0, 0.0, 30.0, 0.01));
spinnerU.addChangeListener(new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent e) {
        voltage = (double) spinnerU.getValue();
        lbSpannung.setText(String.format(Locale.US, "%.2f", voltage));
        System.out.println("volt: " + voltage + ", 100x: "  + Math.round((voltage * 100)));
        slider.setValue((int) voltage * 100);
    }
});

output: 
volt: 0.08, 100x: 8
volt: 0.09, 100x: 9
volt: 0.09999999999999999, 100x: 10
volt: 0.1, 100x: 10 

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
NeariX
  • 43
  • 1
  • 6
  • Possible duplicate of [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – QBrute Oct 27 '19 at 11:11
  • *"(0.069999999999 * 100 would be 6 and not 7!)"* No it wouldn't. It'd be a number very close to 7. – Andrew Thompson Oct 30 '19 at 12:15
  • @AndrewThompson It was. Because it would result in 6.9999 and somehow would get rounded to 6 and not 7. – NeariX Dec 30 '19 at 23:52

1 Answers1

0

The problem is not with the JSpinner.

You are using a double as model. The type double cannot store values with arbitrary precision. In fact it can't store certain values at all.

You can read more floating point in IT here.

If you want to store precise values you need a kind of integer type.

Hauke Ingmar Schmidt
  • 11,559
  • 1
  • 42
  • 50