Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8220811

SpinnerNumberModel floating point rounding issue

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Windows 7 professional. Java 1.8.0_181 (64 bit)

      A DESCRIPTION OF THE PROBLEM :
      A test case to demonstrate this bug is having a min of negative 0.15 and an increment of 0.05. When the spinner is bumped up to (0.10) then back down to (0.15) the double increment results in tail noise of a value like (0.1500000012). That value is beyond the min of (0.15) so the SpinnerNumberModel does not do the change and the spinner remains stuck at (0.10).

      REGRESSION : Last worked in version 8u181

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the code provided. A small window will appear with a JSpinner showing (0.15).
      Click the up button to change the displayed value to (0.10).
      Click the down arrow to change back to the initial and min value of (0.15).



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After spinning from the initial (0.15) up to (0.10) then trying to spin back down to the min of (0.15) it should go back to (0.15).
      ACTUAL -
      Spinner won't go below (0.10).

      ---------- BEGIN SOURCE ----------
      package X
      import javax.swing.*;
      import javax.swing.event.ChangeEvent;
      import javax.swing.event.ChangeListener;
      import java.awt.*;

      public class Main
      {

         public static void main(String[] args)
         {
            JFrame frame = new JFrame();
            frame.setSize(200, 80);
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());
            final JSpinner spinner = new JSpinner(new SpinnerNumberModel(-0.15, -0.150001, 1.0, 0.05));
            panel.add(spinner, BorderLayout.SOUTH);
            frame.add(panel);
            spinner.addChangeListener(new ChangeListener()
            {
               public void stateChanged(ChangeEvent e)
               {
                  System.out.println("spinner: " + ((Number) spinner.getValue()).doubleValue());
               }
            });

            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use a min value that is slightly lower than the min like -0.1500001. This is a hack to get around the rounding error in SpinnerNumberModel incrValue() method.
      Rounding occurs here:
       if ((value instanceof Float) || (value instanceof Double)) {
                  double v = value.doubleValue() + (stepSize.doubleValue() * (double)dir);

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: