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

floating point inaccuracy; inconsistency between platforms w same Java version

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P4 P4
    • None
    • 7
    • core-libs
    • x86
    • windows_vista

      FULL PRODUCT VERSION :
      java version "1.7.0-ea"
      Java(TM) SE Runtime Environment (build 1.7.0-ea-b140)
      Java HotSpot(TM) Client VM (build 21.0-b10, mixed mode, sharing)

      java version "1.6.0_24"
      Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
      Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.0.6002]
      Microsoft Windows XP [Version 5.1.2600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      test on Windows Vista 64 bit
      test on Windows XP 32 bit
      test on Solaris 10

      A DESCRIPTION OF THE PROBLEM :
      floating point values in the Java virtual machine on windows platforms have accuracy issues and ARE NOT CONSISTENT with the same java version on other platforms. This affects both float and double values and all updates of Java 1.6 that we tested, but the accuracy issues appears to be only on the Windows platforms.

      Now before I get a dismissive response regarding accuracy problems inherant in binary floating point values, I assure you I am well aware of this fact. However, most modern computer systems and their languages, including C++, Python, PERL, and Java purport to be complying with the IEEE 754 implementation standards. If this were the case, you would expect the results for representation of various numbers to be the same across systems, and of course they are not. This is ok, as long as there is some acceptable threshhold for representational accuracy and consistency between languages and platforms. For base 10 numbers, we need that threshhold to be 6 digits past the decimal place. In all of our tests, on all platforms this threshhold appears to be met EXCEPT Java on Windows. This basis is not arbitrary, and here is the background:

      There is a proliferation of GIS applications and "location aware" applications now. With satellite imagery and street level maps the norm, there IS an expectation of 1-meter accuracy. In our case, we provide mission critical command and control software where 1-meter accuracy is an operational requirement. Most software uses double precision numbers to represent latitude and longitude in decimal degrees. This data is passed back and forth between numerous systems, so deciding to use BigDecimal or other representation is just not an option, since in the end it must convert back to a double. The 5th digit past the decimal point is roughly equivalent to 1-meter accuracy for a decimal degree value, thus representational accuracy to the 6th digit is required.

      We discovered that randomly our JUnit tests for GEOREF (World Geodetic Reference System) would fail when a position would get mapped to the wrong (adjacent)grid reference, but only on Windows. It is the java double representation issues that are causing this. We have a set of values that we can share, but here is the example we have been using in our testing:

      A longitude value of -99.7, that needs to be normalized by 180 degrees. The result (180 -99.7) is of course 80.3. Here are the results of how the value is represented, formatting limited to just 8 decimal places, with a space following the 6th digit (the required accuracy):

      80.300000 00 (Java 1.6 VM on Solaris 10)
      80.300000 10 (C++ (gcc) on Solaris 10)
      80.300000 10 (C++ (MS Visual Basic) on Windows XP)

      80.300003 05 (Java 1.7, 1.6 on Windows XP 32 bit)
      80.300003 05 (Java 1.7, 1.6 on Windows Vista 64 bit)

      You could argue that this specific number has a poorer representation on Java/Windows, but there are other number that the other systems will represent more poorly. However, our unit testing has not shown this to be the case (yet). Even so, why is the value represented better on Solaris?

      This is an extremely difficult problem to overcome for java developers and I think the Java virtual machine can be improved to at least match the 6 digit accuracy that everyone seems to be able to provide.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Simply assign the result of 180 -99.7 to a float or double to see how it is represented.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Expected 80.30000010, like other IEEE 754 implementations, accurate to the 6 digit past the decimal
      ACTUAL -
      80.30000305, accurate only to he 5th digit past the decimal

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      double test = (180.0 - 99.7);
      NumberFormat formatter = NumberFormat.getInstance();
      formatter.setMinimumFractionDigits(8);
      System.out.println(formatter.format(test));
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      There are no known workarounds if you must use a double to exchange data with other software systems.

            mduigou Mike Duigou
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: