Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6837951

Incorrect answer while summing serialized / deserialized BigDecimals

XMLWordPrintable

    • b01
    • b07
    • x86
    • solaris_8, windows_xp

        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.

              xlu Xiaobin Lu (Inactive)
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: