JDK-4755500 : REGRESSION: calling Math.round(NaN) can break subsequent calls to Math.round()
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 1.4.1
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_98,windows_2000
  • CPU: x86
  • Submitted: 2002-09-30
  • Updated: 2017-08-17
  • Resolved: 2002-10-23
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.2 mantisFixed
Related Reports
Duplicate :  
Relates :  
Description

Name: gm110360			Date: 09/30/2002


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


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

ADDITIONAL OPERATING SYSTEMS :

We tested against Linux and Solaris and did not see the bug.


A DESCRIPTION OF THE PROBLEM :
After calling Math.round(double) a number of times,
including some calls to Math.round(Double.NaN), subsequent
calls to Math.round(double) may incorrectly return 0.

There are a number of ways to reproduce this, but the
easiest thing to do is just to call Math.round(Double.NaN)
2000 times.  The next time you call Math.round(double) the
result will always be 0, regardless of what you supply as
an argument.

Math.round(float) seems to be affected also.


REGRESSION.  Last worked in version 1.4

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Make 2000 calls to Math.round(Double.NaN)
2. Make one call to Math.round(double) using a whole number
argument (e.g. 1d or 12345d)


EXPECTED VERSUS ACTUAL BEHAVIOR :
The result is 0 when it should be equal to the argument
(e.g. 1 or 12345)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
We discovered this bug after experiencing the following two exceptions during
calls to Graphics.drawLine() somewhere inside the paint method of one of our
components:

sun.dc.pr.PRException: endPath: bad path
        at sun.dc.pr.Rasterizer.endPath(Rasterizer.java:537)
        at sun.java2d.pipe.DuctusRenderer.createShapeRasterizer
(DuctusRenderer.java:374)
        at sun.java2d.pipe.DuctusShapeRenderer.renderPath
(DuctusShapeRenderer.java:57)
        at sun.java2d.pipe.DuctusShapeRenderer.draw(DuctusShapeRenderer.java:45)
        at sun.java2d.pipe.PixelToShapeConverter.drawLine
(PixelToShapeConverter.java:34)
        at sun.java2d.SunGraphics2D.drawLine(SunGraphics2D.java:1954)
        ...



sun.dc.pr.PRError: setPenT4: invalid pen transformation (singular)
        at sun.dc.pr.PathStroker.setPenT4(Native Method)
        at sun.dc.pr.Rasterizer.setPenT4(Rasterizer.java:205)
        at sun.java2d.pipe.DuctusRenderer.createShapeRasterizer
(DuctusRenderer.java:260)
        at sun.java2d.pipe.DuctusShapeRenderer.renderPath
(DuctusShapeRenderer.java:57)
        at sun.java2d.pipe.DuctusShapeRenderer.draw(DuctusShapeRenderer.java:45)
        at sun.java2d.pipe.PixelToShapeConverter.drawLine
(PixelToShapeConverter.java:34)
        at sun.java2d.SunGraphics2D.drawLine(SunGraphics2D.java:1954)
        ...


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class MathBugTest {
  
  public static void main(String[] args) {
    System.out.println(Math.round(1d));  // prints "1", as expected
    for (int i=0; i<2000; i++) {
      Math.round(Double.NaN);
    }
    System.out.println(Math.round(1d));  // prints "0", which is wrong
  }
  
}
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Hack the java.lang.Math.round(float/double) methods so that
they test for NaN prior to calling StrictMath.round()

Release Regression From : 1.4.0_02
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Review ID: 165064) 
======================================================================

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

EVALUATION This is a bug in the d2l conversion stub which was introduced for speed in 1.4.1. In the NaN case we weren't popping the argument off the FPU stack, which for some reason caused subsequent flds to be messed up. Will be fixed in 1.4.2 and recommended to be backported to 1.4.1_02. ###@###.### 2002-10-04 Revised test case with pass/fail result: public class MathBugTest { public static void main(String[] args) { // Note: it's really only necessary to run this loop 8 times to // reproduce the bug, but the 2000-length loop causes compilation // of Math.round() without any other command-line flags. // A bug in the d2l NaN case was causing overflow of the FPU // stack, yielding subsequent wrong results for flds. for (int i=0; i<2000; i++) { Math.round(Double.NaN); } if (Math.round(1d) != 1) { throw new RuntimeException("TEST FAILED"); } System.out.println("Test passed."); } } ###@###.### 2002-10-04
04-10-2002