Details
-
Bug
-
Resolution: Fixed
-
P1
-
1.4.1_02, 1.4.2
-
b23
-
x86
-
windows_2000
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2069243 | 5.0 | Chet Haase | P1 | Resolved | Fixed | tiger |
Description
Name: rmT116609 Date: 05/08/2003
FULL PRODUCT VERSION :
D:\Temp>"c:\Program Files\Java\j2re1.4.2\bin\java" -version
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b19)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b19, mixed mode)
FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
On this small benchmark application, the Pi calculation gives a wrong result, when running on JDK 1.4.2 Beta.
This does not occur with other JDK versions or when extracting the Pi calculation code from the program. So I suppose it depends on the context (GC running before...). Using strictfp does not change the behavior.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the Zjb program
java -cp . Zjb
EXPECTED VERSUS ACTUAL BEHAVIOR :
With other JDK: Pi=3.141591698659554
With JDK 1.4.2 Beta: Pi=3.1413934230804443
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.List;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
/**
* Zjb: Zaurus Java Bechmark
* @author GenePi
*/
class Zjb
extends Frame
{
static Zjb _mainWindow;
/**
* Number of benchmark runs.
*/
private final TextField _runs;
/**
* Results list
*/
private final List _results;
/**
* Wait, program is thinking...
*/
private final Label _wait;
/**
* Start button
*/
private final Button _start;
/**
* Benchmark running
*/
private volatile boolean _running = false;
/**
* Layout the main window.
**/
Zjb()
{
super("Zaurus java benchmark 1.0");
setLayout(new BorderLayout());
// Input fields
Panel top = new Panel(new GridLayout(1, 0));
top.add(new Label("Number of runs"));
_runs = new TextField("1");
top.add(_runs);
add(top, BorderLayout.NORTH);
// Results list
_results = new List();
add(_results, BorderLayout.CENTER);
// Start button
final Panel bottom = new Panel(new FlowLayout(FlowLayout.RIGHT));
_wait = new Label();
bottom.add(_wait);
_start = new Button("Start");
_start.addActionListener(new ActionListener()
{
public void actionPerformed(final ActionEvent evt)
{
if (!_running)
{
// Clear previous results and start benchmark.
_results.clear();
_start.setLabel("Stop");
_wait.setText("Running... ");
bottom.validate();
_running = true;
}
else
{
_start.setLabel("Start");
_wait.setText("");
_running = false;
}
}
});
bottom.add(_start);
// Quit button
final Button quit = new Button("Quit");
quit.addActionListener(new ActionListener()
{
public void actionPerformed(final ActionEvent evt)
{
System.exit(0);
}
});
bottom.add(quit);
add(bottom, BorderLayout.SOUTH);
// Exit when main window closes
addWindowListener(new WindowAdapter()
{
public void windowClosing(final WindowEvent evt)
{
System.exit(0);
}
});
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
setSize(dim);
validate();
}
/**
* The benchmarks
*
* @param runs Number of runs
*/
private static void runBenchmarks(final int runs)
{
long start;
long end;
long totalStart;
long totalEnd;
// Integer arithmetic
start = System.currentTimeMillis();
totalStart = start;
int resultInt = 0;
for (int i = 0; i < runs; i++)
{
resultInt = ackerman(3, 9);
// resultInt = ackerman(3, 7);
}
end = System.currentTimeMillis();
_mainWindow._results.add("Integer arithmetic: " + ((end - start) / 1000.0) + " s [Ack(3,9)=" + resultInt + "]");
if (!_mainWindow._running)
{
return;
}
// Float and double
start = System.currentTimeMillis();
double resultDouble = 0.0;
for (int i = 0; i < runs; i++)
{
resultDouble = 0.0;
for (int j = 1; j < 1000000; j++)
{
resultDouble += 1.0 / ((double) j * (double) j);
}
resultDouble = Math.sqrt(resultDouble * 6.0);
}
end = System.currentTimeMillis();
_mainWindow._results.add("Double arithmetic: " + ((end - start) / 1000.0) + " s [Pi=" + resultDouble + "]");
if (!_mainWindow._running)
{
return;
}
// Big operations
start = System.currentTimeMillis();
BigInteger resultBig = new BigInteger("1");
for (int i = 0; i < runs; i++)
{
resultBig = fact(3000);
}
end = System.currentTimeMillis();
_mainWindow._results.add("Infinite arithmetic: " + ((end - start) / 1000.0) + " s [3000!=" + resultBig.toString().substring(1, 20) + "...]");
if (!_mainWindow._running)
{
return;
}
// Strings
start = System.currentTimeMillis();
String resultString = null;
for (int i = 0; i < runs; i++)
{
final String alphabet = " qwertyuioplkjhgfdsazxcvbnm0789456123./*";
StringBuffer buf = new StringBuffer();
for (int j = 0; j < 100000; j++)
{
int pos = j % alphabet.length();
buf.append(alphabet.substring(pos, pos + 1));
}
resultString = buf.toString();
}
end = System.currentTimeMillis();
_mainWindow._results.add("Strings: " + ((end - start) / 1000.0) + " s [" + resultString.substring(1, 20) + "...]");
if (!_mainWindow._running)
{
return;
}
// Drawing
start = System.currentTimeMillis();
for (int i = 0; i < runs; i++)
{
final int size = 200;
Dialog dialog = new Dialog(_mainWindow, "Drawing...", true);
dialog.add(new TestPanel(dialog));
dialog.setSize(size, size);
dialog.show();
}
end = System.currentTimeMillis();
_mainWindow._results.add("Drawing: " + ((end - start) / 1000.0) + " s");
if (!_mainWindow._running)
{
return;
}
// File copy
start = System.currentTimeMillis();
String resultIO = "OK";
loopIO:
for (int i = 0; i < runs; i++)
{
final String tempName = "/tmp/Zjb.tmp";
try
{
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempName));
for (int j = 0; j < 1000000; j++)
{
out.write((byte) j);
}
out.close();
BufferedInputStream in = new BufferedInputStream(new FileInputStream(tempName));
for (int j = 0; j < 1000000; j++)
{
int r = in.read();
if ((byte) r != (byte) j)
{
resultIO = "Failed";
System.err.println("Content mismatch at " + j);
break loopIO;
}
}
in.close();
new File(tempName).delete();
}
catch(IOException ioe)
{
resultIO = "Failed";
System.err.println(ioe);
break loopIO;
}
}
end = System.currentTimeMillis();
_mainWindow._results.add("Files I/O: " + ((end - start) / 1000.0) + " s [1MB written/read/deleted: " + resultIO + "]");
totalEnd = end;
_mainWindow._results.add("");
_mainWindow._results.add("Total: " + ((totalEnd - totalStart) / 1000.0) + " s");
}
/**
* Utility functions: Ackerman function
*
* @param m
* @param n
*/
private static int ackerman(final int m, final int n)
{
if (m == 0)
{
return (n + 1);
}
else if (n == 0)
{
return (ackerman(m - 1, 1));
}
else
{
return ackerman(m - 1, ackerman(m, (n - 1)));
}
}
/**
* Factorial of big numbers.
*
* @param n
* @return
*/
private static BigInteger fact(final int n)
{
final BigInteger one = new BigInteger("1");
BigInteger num = new BigInteger("1");
BigInteger fact = new BigInteger("1");
for (int i = 2; i <= n; i++)
{
num = num.add(one);
fact = fact.multiply(num);
}
return fact;
}
/**
* Benchmark entry point.
*
* @param args Command line arguments
*/
public static void main(String[] args)
{
_mainWindow = new Zjb();
_mainWindow.show();
synchronized (Zjb.class)
{
while (true)
{
try
{
Zjb.class.wait(500L);
}
catch (InterruptedException ie)
{
// Wake
}
if (_mainWindow._running)
{
try
{
runBenchmarks(Integer.parseInt(_mainWindow._runs.getText()));
}
catch (NumberFormatException nfe)
{
_mainWindow._runs.setText("1");
runBenchmarks(1);
}
_mainWindow._running = false;
_mainWindow._start.setLabel("Start");
_mainWindow._wait.setText("");
}
}
}
}
}
class TestPanel
extends Panel
{
/**
* The dialog containing the panel.
*/
private final Dialog _dialog;
TestPanel(final Dialog dialog)
{
_dialog = dialog;
}
public void paint(final Graphics g)
{
Dimension dim = getSize();
g.setColor(Color.white);
g.fillRect(0, 0, dim.width, dim.height);
for (int i = 0; i < 1000; i++)
{
Color color = new Color((int) (Math.random() * Integer.MAX_VALUE));
int x = (int) (Math.random() * dim.width);
int y = (int) (Math.random() * dim.height);
int width = (int) (Math.random() * dim.width);
int height = (int) (Math.random() * dim.height);
g.setColor(color);
g.fillRect(x, y, width, height);
}
g.setColor(Color.white);
g.fillRect(0, 0, dim.width, dim.height);
for (int i = 0; i < 1000; i++)
{
Color color = new Color((int) (Math.random() * Integer.MAX_VALUE));
int x = (int) (Math.random() * dim.width);
int y = (int) (Math.random() * dim.height);
int width = (int) (Math.random() * dim.width);
int height = (int) (Math.random() * dim.height);
g.setColor(color);
g.fillOval(x, y, width, height);
}
// Hide dialog when finished
_dialog.hide();
}
}
---------- END SOURCE ----------
(Review ID: 184686)
======================================================================
Attachments
Issue Links
- backported by
-
JDK-2069243 REGRESSION: Wrong double calculation result for Pi (Windows only)
- Resolved
- relates to
-
JDK-4644270 EXCEPTION_FLT_DIVIDE_BY_ZERO with Floating Point Arithmetic using external dll
- Closed
-
JDK-4351747 VM ERROR, EXCEPTION_FLT_INVALID_OPERATION
- Resolved