-
Bug
-
Resolution: Fixed
-
P4
-
1.2.0
-
1.2.2
-
x86
-
windows_nt
Name: dkC59003 Date: 11/27/98
Sample program below contains methods ( pass(); passStat() ) that
store value to field and get value from the field immediately.
Log shows that Symantec JIT v3.00.078(x) uses double-extended format
for value, that is stored, and pass that unrounded double-extended value
to 'dmul' instruction, following the 'getfield'/'getstatic' instruction.
The same test for type 'float' doesn't fail.
Sample fails on JDK 1.2 FCS-U and previous releases (checked down to
JDK 1.2 FCS-M ) for win32 with JIT enabled. Releases for sparc and x86
and for win32 without JIT run this sample without errors.
========================================= fpm01802m2.java
import java.io.PrintStream;
public class fpm01802m2 {
double Y;
static double sY;
static double mul1;
static double mul2;
double pass(double x) {
Y = x*mul1; // mul1 == 2.0 and mul2 == 0.5 for Inf case
return Y*mul2; // mul1 == 0.5 and mul2 == 2.0 for Zero case
}
double passStat(double x) {
sY = x*mul1;
return sY*mul2;
}
public static void main(String argv[]) {
PrintStream out = System.out;
fpm01802m2 obj = new fpm01802m2();
boolean OK = true;
double X, sX;
X = Double.MAX_VALUE; // ======================= Infinity case
for (int i=120; i!=0; i--)
X /= 2;
sX = X;
obj.mul1 = 2;
obj.mul2 = 0.5f;
for (int i=120; i!=0; i--) { // Intermediate value achieves Double.MAX_VALUE * 2
X = obj.pass( X*2); // so it must be rounded to Double.POSITIVE_INFINITY
sX = obj.passStat(sX*2); // while storing to field
}
if (X != Double.POSITIVE_INFINITY) {
println(X, obj.Y, obj.Y*obj.mul2, "POSITIVE_INFINITY after obj.pass()", out);
OK = false;
}
if (sX != Double.POSITIVE_INFINITY) {
println(sX, obj.sY, obj.sY*obj.mul2, "POSITIVE_INFINITY after obj.passStat()", out);
OK = false;
}
X = Double.MIN_VALUE; // ======================= Zero case
for (int i=120; i!=0; i--)
X *= 2;
sX = X;
obj.mul1 = 0.5f;
obj.mul2 = 2;
for (int i=120; i!=0; i--) { // Intermediate value achieves Double.MIN_VALUE * 0.5
X = obj.pass( X/2); // so it must be rounded to 0.0
sX = obj.passStat(sX/2); // while storing to field
}
if (X != 0) {
println(X, obj.Y, obj.Y*obj.mul2, "0 after obj.pass()", out);
OK = false;
}
if (sX != 0) {
println(sX, obj.sY, obj.sY*obj.mul2, "0 after obj.passStat()", out);
OK = false;
}
if ( OK )
out.println(" Passed");
}
static void println(double x, double y, double fm, String s, PrintStream out) {
out.println(show(x)+" != "+s);
out.println("while field value == "+show(y)+"; field value * "+mul2+" == "+show(fm));
}
static String show(double x) {
return (""+x)+(" (0x"+
Long.toHexString(Double.doubleToLongBits(x)) ) +"L)";
}
}
========================================= fpm01802m2.trace
H:\ld22\java\inev\work\jck12fp\fails\12fcsU>H:\ld25\java\dest\jdk1.2fcsU\win32\bin\java.exe fpm01802m2
1.7976931348623157E308 (0x7fefffffffffffffL) != POSITIVE_INFINITY after obj.pass()
while field value == Infinity (0x7ff0000000000000L); field value * 0.5 == Infinity (0x7ff0000000000000L)
1.7976931348623157E308 (0x7fefffffffffffffL) != POSITIVE_INFINITY after obj.passStat()
while field value == Infinity (0x7ff0000000000000L); field value * 0.5 == Infinity (0x7ff0000000000000L)
4.9E-324 (0x1L) != 0 after obj.pass()
while field value == 0.0 (0x0L); field value * 2.0 == 0.0 (0x0L)
4.9E-324 (0x1L) != 0 after obj.passStat()
while field value == 0.0 (0x0L); field value * 2.0 == 0.0 (0x0L)
H:\ld22\java\inev\work\jck12fp\fails\12fcsU>
=========================================
Note that 1.7976931348623157E308 == Double.MAX_VALUE and 4.9E-324 == Double.MIN_VALUE
======================================================================