JDK-4660849 : Float.floatToRawIntBits misses bit 22 if input is NaN
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2002-04-01
  • Updated: 2002-06-12
  • Resolved: 2002-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.1 hopperFixed
Related Reports
Relates :  
Description

Name: gm110360			Date: 04/01/2002


FULL PRODUCT VERSION :
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
When this program runs...

class TestFloatToInt {
    public static void main(String args[]) {
        int myInt = -7132611;
        System.out.println("Start value: " + myInt + "  in
hex: " + Integer.toHexString(myInt));

        float convertToFlt = Float.intBitsToFloat(myInt);
        System.out.println("Converted, using
Float.intBitsToFloat: " + convertToFlt);

        int anotherInt = Float.floatToRawIntBits
(convertToFlt);
        System.out.println("After
Float.floatToRawIntBits: " + anotherInt +
            "  in hex: " + Integer.toHexString(anotherInt));
    }
}

it produces the following output...

Start value: -7132611  in hex: ff932a3d
Converted, using Float.intBitsToFloat: NaN
After Float.floatToRawIntBits: -2938307  in hex: ffd32a3d

indicating that bit number 22 is incorrectly set during the
conversion.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the program


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected output:

Start value: -7132611  in hex: ff932a3d
Converted, using Float.intBitsToFloat: NaN
After Float.floatToRawIntBits: -2938307  in hex: ff932a3d

Actual output:

Start value: -7132611  in hex: ff932a3d
Converted, using Float.intBitsToFloat: NaN
After Float.floatToRawIntBits: -2938307  in hex: ffd32a3d

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
class TestFloatToInt {
    public static void main(String args[]) {
        int myInt = -7132611;
        System.out.println("Start value: " + myInt + "  in hex: " +
            Integer.toHexString(myInt));

        float convertToFlt = Float.intBitsToFloat(myInt);
        System.out.println("Converted, using Float.intBitsToFloat: " +
            convertToFlt);

        int anotherInt = Float.floatToRawIntBits(convertToFlt);
        System.out.println("After Float.floatToRawIntBits: " + anotherInt +
            "  in hex: " + Integer.toHexString(anotherInt));
    }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
I was using this method when trying to byte swap floats
before writing to disk. I can find other ways to do this.
(Review ID: 144670) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: hopper FIXED IN: hopper INTEGRATED IN: hopper VERIFIED IN: hopper-beta
14-06-2004

EVALUATION What is happending here may be hard to "correct" in the intBitsToFloat and floatToRawIntBits methods. Specifically, in IEEE 754 there are two kinds of NaN values, quiet NaNs and signaling NaNs. Arithmetic operations turn signaling NaNs into quiet NaNs (on the x86, by writing a one into bit 22 of a float). The mere act of copying a floating-point value can also trigger this conversion, including a load to or store from the FPU. In particular, the copying of a function return value may be triggering the conversion. Therefore, both conversion methods may actually be working as expected; on some processors it may just be impossible to pass a signaling NaN into floatToRawIntBits (using intBitsToFloat is the only way to possibly create a signaling NaN in Java). Some processors do not perform the NaN conversion on a copy; for example, the test program works as expected on SPARC but not on x86. The analagous problem also occurs for double values on the x86. I'll consult some C gurus but I believe the issue may be inherent in the C calling conventions. If so, this bug will be 'closed - will not fix' but I will add a note about this possibility in the JavaDoc. Perserving the NaN flavor is not necessary for floating-point compuations in Java; Java hides the functional difference between signaling and quiet NaNs (namely that the former signal the IEEE 754 invalid condition). The nio classes can be used to change endianess of buffers. ###@###.### 2002-04-04 After some investigation, the C and Java calling conventions on the x86 prevent the expected functionality from working here. Amended spec to clarify this point -- functionality will not be added. ###@###.### 2002-04-09
09-04-2002