United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6833879 Assigning positive zero is ignored when old value is negative zero
JDK-6833879 : Assigning positive zero is ignored when old value is negative zero

Details
Type:
Bug
Submit Date:
2009-04-24
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
hotspot
OS:
solaris_nevada
Sub-Component:
compiler
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
6u13
Fixed Versions:
hs16 (b03)

Related Reports
Backport:
Backport:

Sub Tasks

Description
In Apache Derby there is some code that performs normalization of floating point values. The results from this normalization tend to vary, although I believe the results should be well-defined. The code is essentially like this:

// turn negative zero into positive zero
if (v == 0.0f)
    v = 0.0f;
return v;

Since (-0.0f == 0.0f) evaluates to true per the language specification, v should be assigned the value 0.0f (positive zero) if the original value of v is 0.0f or -0.0f (negative zero). Hence, negative zero should never be returned by this code. However, it sometimes does return negative zero.

It looks like this happens when the runtime optimizer has kicked in. It probably thinks the if statement is without side-effects and optimizes it away.

To reproduce, compile and run this Java class:

public class Normalize {

    public static void main(String[] args) {
        System.out.println("normalize(-0.0f): " + normalize(-0.0f));
        for (int i = 0; i < 1000000; i++) {
            normalize(-0.0f);
        }
        System.out.println("normalize(-0.0f): " + normalize(-0.0f));
    }

    public static float normalize(float v) {
        if (v == 0.0f) v = 0.0f;
        return v;
    }
}

When I run this code with the server VM, I get this output most of the time:

$ java -server Normalize
normalize(-0.0f): 0.0
normalize(-0.0f): -0.0

That is, the first time normalize(-0.0f) is called, it returns positive zero as expected. The last time normalize(-0.0f) is called, it returns negative zero.

Occationally with the server VM, and every time with the client VM or with -Xint, I see this output (which is what I expect to see):

$ java -client Normalize 
normalize(-0.0f): 0.0
normalize(-0.0f): 0.0

                                    

Comments
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/36ee9b69616e
                                     
2009-05-06
PUBLIC COMMENTS

Another, perhaps faster, idiom to get rid of negative zero is just

v = v + 0.0f;

If v is -0.0, -0.0 + (+0.0) results in (+)0.0 and other values are unchanged by the addition.
                                     
2009-05-06
EVALUATION

Approved for JDK 7 M3 build 3.
                                     
2009-05-07



Hardware and Software, Engineered to Work Together