Hi,
Requirement is : Once user enters a decimal number , it should be stored in Db2 as PAcked Decimal (COMP3)
Application is running on AIX(Encoding : ASCII) and DB2 is in Mainframe(Encoding : EBCDIC )
JDK Version: 1.5
The follwoing logic is used to convert decimal to PACKEDDEIMAL and then to EBCDIC Encoding.
Problem is : When the number "154.10" is converted to EBCDIC it is stored as 254.10. When 154.10 and 254.10 ae converted, we are getting the same bytes after encoding (for both numbers). For other numbers it is working fine. This problem is occurrent when 1 followed by 5 (For Ex: 154.10, 451.56 , etc..). Please advise if there is any problem with JDK1.5 encoding or Is there any other way to convert deciaml numbers into Packed decimal format?
package com.test.data;
public class TestPackDec1 {
/**
* @param args
*/
public static void main(
String[] args) throws Exception{
String number = "154.10";
System.out.println(" Covert "+number+ " Using Packed Decimalm PackDec class ************");
byte[] buffr1 = new byte[6];
stringToPack(number, buffr1, 0, 6 );
System.out.println("Packed decimal Bytes " );
printByte(buffr1);
String encodedStr = new String(buffr1, "Cp037");
System.out.println("Encoded String " +encodedStr);
System.out.println("Encoded String Bytes " );
printByte(encodedStr.getBytes());
System.out.println("Encoded String Bytes2 Cp037 ");
printByte(encodedStr.getBytes("Cp037"));
}
/**
* Converts String to packed decimal number. Decimal points, commas and
* spaces are ignored. Sign character is processed. Avoid multiple signs.
* Characters other than digits are invalid and will cause DataException.
* Comma, blank, period, dollar sign and plus are ignored. Scaling and
* exponents are not valid.
*
* @param str
* String of number to convert
* @return byte array of packed decimal, 16 long
*/
public static byte[] stringToPack(String str) throws Exception {
int i; // string index
int j; // byte array index
boolean nibble_ordinal = false;
char ch1;
byte nibble;
int strlen = str.length();
byte[] pknum = new byte[16];
for (i = 0; i < 16; i++) { // initialize to zero
pknum[i] = 0;
}
i = strlen - 1;
j = 15; /* byte index */
pknum[j] = 12; // start with positive sign
while (i > -1) {
ch1 = str.charAt(i);
switch (ch1) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
nibble = (byte) Character.getNumericValue(ch1);
if (nibble_ordinal) {
pknum[j] = (byte) (pknum[j] | nibble);
nibble_ordinal ^= true;
} else {
pknum[j] = (byte) (pknum[j] | nibble << 4);
nibble_ordinal ^= true;
--j;
}
--i; // get next char
break;
case ',':
case ' ':
case '.':
case '$':
case '+':
--i; // get next char
break;
case '-':
pknum[15] = (byte) (pknum[15] & 0xf0);
pknum[15] = (byte) (pknum[15] | 0x0d);
--i; // get next char
break;
default:
throw new Exception("Data Exception : Invalid decimal digit: " + ch1);
}
}
return (pknum);
}
/**
* Convenience method to convert a String to packed decimal. The packed
* number is stored in an existing array.
*
* @param str
* Number to be converted
* @param bytearray
* Contains result
* @param offset
* Location in array
* @param len
* Number of bytes of result
* @throws DecimalOverflowException
* If result is larger than result length
*/
public static void stringToPack(String str, byte[] bytearray, int offset,
int len) throws Exception {
byte[] pknum = stringToPack(str); /* get packed num of length 16 */
int pklen = pknum.length;
if (len < pklen) // check to see of number too big
if (pknum[pklen - len - 1] != 0)
throw new Exception("DecimalOverflowException : Number too big");
int i = offset + len - 1;
int j = pklen - 1;
int k;
for (k = 0; k < len; k++) {
bytearray[i] = pknum[j];
--i;
--j;
}
}
public static void printByte(byte[] bytearr){
if (bytearr != null) {
for (int i=0; i < bytearr.length; i++){
System.out.print(bytearr[i] + " ");
}
System.out.println();
}
}
}