FULL PRODUCT VERSION :
java version "1.6.0_14-ea"
Java(TM) SE Runtime Environment (build 1.6.0_14-ea-b03)
Java HotSpot(TM) Client VM (build 14.0-b12, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP / Professional Edition x64 / 2003 / SP3
A DESCRIPTION OF THE PROBLEM :
When this program is run with JDKs prior to jdk1.6.0_14 the correct answer is given and no errors occur. When run with jdk1.6.0_14 (up to b05) then the incorrect answer is given and an error is detected.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error printed on System.out. The answer is: 1108240.4666936930160
ACTUAL -
An error printed on System.out. Bad answer is: 781240.4666940200160
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
package com.certive.cs.util;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
public class BDTest
{
protected static String[] S_arrayOfStringValues = new String[]
{
"117000.0", "83200.0", "0", "0", "0", "5280.0", "0", "69426.0",
"6500.0", "7603.4919740918050", "7819.1205269716930", "9506.8541926295180",
"31600.0", "39828.0", "71200.0", "24000.0", "14760.0", "84000.0",
"0", "113184.0", "96333.0", "279000.0", "48000.0"
};
/**
* @param args
*/
public static void main(String[] args)
{
String sFile = "C:/BDData.bd";
BigDecimal[] arrayOfBigDecimals = null;
// convert strings to BigDecimals
arrayOfBigDecimals = toBigDecimals( S_arrayOfStringValues );
// write to the file?
write( arrayOfBigDecimals, sFile );
// read from the file?
arrayOfBigDecimals = read( sFile );
// print out the sum of the big decimals
System.out.print( sum( arrayOfBigDecimals ) );
}
protected static void write( BigDecimal[] abd, String sFile )
{
try
{
FileOutputStream fos = new FileOutputStream( sFile );
DataOutputStream dos = new DataOutputStream( fos );
int iValues = abd.length;
dos.writeInt( iValues );
for( int i = 0; i < iValues; i++ )
{
BigDecimal bd = abd[i];
byte[] aBytes = bd.unscaledValue().toByteArray();
short iBytes = (short) aBytes.length;
short iScale = (short) bd.scale();
dos.writeShort( iBytes );
dos.write( aBytes );
dos.writeShort( iScale );
}
if ( dos != null )
dos.close();
}
catch( Throwable t )
{
t.printStackTrace();
}
}
protected static BigDecimal[] read( String sFile)
{
BigDecimal[] abd = null;
try
{
FileInputStream fis = new FileInputStream( sFile );
DataInputStream dis = new DataInputStream( fis );
int iValues = dis.readInt();
abd = new BigDecimal[iValues];
for( int i = 0; i < iValues; i++ )
{
int iBytes = dis.readShort();
byte[] aBytes = new byte[iBytes];
dis.read( aBytes );
int iScale = dis.readShort();
abd[i] = new BigDecimal(new BigInteger(aBytes), iScale);
}
if ( dis != null )
dis.close();
}
catch( Throwable t )
{
t.printStackTrace();
}
return abd;
}
protected static BigDecimal sum( BigDecimal[] abd)
{
int iLen = abd == null ? 0 : abd.length;
BigDecimal bdSum = iLen > 0 ? new BigDecimal( 0 ) : null;
for( int i = 0; i < iLen; i++ )
{
BigDecimal bdAdd = abd[i];
BigDecimal bdNewSum = bdSum.add( bdAdd );
System.out.println( "Start: " + bdSum + " Add: " + abd[i] + " End: " + bdNewSum );
if ( bdNewSum.intValue() == bdSum.intValue() && bdAdd.intValue() != 0 )
System.out.println( "ERROR! We didn't add a non-zero correctly!" );
bdSum = bdNewSum;
}
return bdSum;
}
protected static BigDecimal[] toBigDecimals( String[] strValues )
{
int iLen = strValues == null ? 0 : strValues.length;
BigDecimal[] abd = new BigDecimal[iLen];
for ( int i = 0; i < iLen; i++ )
{
abd[i] = new BigDecimal( strValues[i] );
}
return abd;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
None. The JDK simply does not give the correct answer.
Release Regression From : 6u14
The above release value was the last known release where this
bug was not reproducible. Since then there has been a regression.