aspose file tools*
The moose likes Beginning Java and the fly likes Packed decimal conversion - Java Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Packed decimal conversion - Java" Watch "Packed decimal conversion - Java" New topic
Author

Packed decimal conversion - Java

Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
Hi,

I get a string from mainframe which contains characters and pack decimals.
Say first 3 digits - char, followed by packed decimal, then char again.

How can i extract the packed decimal based on position and use it in readable form in Java?

Thanks in advance.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36563
    
  16
Please check your private messages.

You could use the substring methods of the String class.
If you can predict what range the leading and trailing characters are, you can design a regular expression to match them and feed it to something like the split method of String.
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
By packed decimal, I assume you mean a number with 2 decimal digits per byte except for the ending byte which has the sign in the last nibble. I forget what valid sign values are, could be C, D and F?? For example given 2 bytes:
the value of 010F would be 10, 023D would be -23

If you read the data into a byte array, you can use shifts and ANDs to stripe off the digits one at a time and accumulate the total value.
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
Thanks for your response.

I get this value as a output from a stored procedure in mainframe environment.
They are returning many fields in single row. I need to extract all the fields of which some of them are packed decimal. How can i store the entire structure in java and retrieve all the fields (char, decimal, etc..)
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
If my definition of packed decimal is correct, here's code to convert it to long.



To convert a record from a main frame to java data, you'll need a field/byte-by-byte layout for the record. Then code can be written to convert each field to a java value like was done above.
[ July 25, 2008: Message edited by: Norm Radder ]
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
Hi Thanks for your response..

Is there any built in method in Java to convert EBCDIC data to ASCII data. I invoke the Stored Procedure in mainframe DB2 and it returns output parameter. In DB2, they have set the return type of the output parameter as VARCHAR.

while getting the out parameter from mainframe-Stored procedure, to which data type in Java do I need to assign to? How can i extract the fields from this data?
Note: the output parameter is concatenation of many fields like CHAR, Packed decimal and is returned as single parameter.
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
If you can layout the fields in the record you receive from the mainframe, code can be written to convert it to java data.
For example EBCDIC to ASCII: in EBCDIC 'A' is 0xC1, in ASCII 0x41. The other characters should also be a one to one conversion.

as single parameter
Does that mean a record of bytes?
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
thanks for the reply.

Yes - what i meant by single parameter is it is record of bytes. DB2 in mainframe returns one out parameter field.

This field has a fixed length layout
say 1-10 : name in char
11-16 : Amt in 6 byte packed decimal (it is a signed decimal with
1 digit for sign, 8 digits before decimal point, 1 digit for decimal point, 2 digits for holding after decimal points)
17-20 : State in char
and so on.

This is the output parameter of stored procedure from DB2. I execute it using callable statement and get the value as callstmt.getString().

Now my question is how i can extract fields fromthis data? when I view the output in IE, the decimal field looks like junk character.

Let me know your suggestions.
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
how i can extract fields from this data

Write a program. Do you have a java programmer available that could help you?

11-16 : Amt in 6 byte packed decimal (it is a signed decimal with
1 digit for sign, 8 digits before decimal point, 1 digit for decimal point, 2 digits for holding after decimal points)

Don't think I've seen/remember this format: s12345678.90
My previous post was for: 0123456s


I view the output in IE

How does the output get from the mainframe to IE? Pass it thru a java conversion program to convert the data to ASCII.

Here's a skeleton of a program to convert EBCDIC to ASCII. It needs the converstion table filled in with the E to A values, I've filled in the few I can remember.
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
Will not JDBC driver automatically take care of converting EBCDIC data from output parameter of Stored procedure (Stored Procedure resides in Mainframe DB2) to ASCII when it comes to client (Client is Unix)?

If it takes care of this, what will happen to packed decimal during this conversion process?
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
try it and see.
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
how do I know in which encoding exactly is a string being returned in the client end?
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 685
Look at the values in the bytes and compare them to what you know they should be.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18150
    
    8

Originally posted by Mary Jane Sam:
Will not JDBC driver automatically take care of converting EBCDIC data from output parameter of Stored procedure (Stored Procedure resides in Mainframe DB2) to ASCII when it comes to client (Client is Unix)?

If it takes care of this, what will happen to packed decimal during this conversion process?
If you have one data item which mixes characters with packed decimal, and if something converts that data item from EBCDIC to Unicode, then that something will mangle the packed decimal data.

But I agree with Norm Radder, you should try it. Asking what will happen isn't very useful -- especially when the answer is "I don't know".
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18150
    
    8

Originally posted by Mary Jane Sam:
how do I know in which encoding exactly is a string being returned in the client end?
This question doesn't quite make sense. Strings in Java don't have encodings. The encodings come into play when an array of bytes is converted into a String. And generally it's not possible to just look at a String and say what encoding was used to convert from bytes.

I think you're going about this wrong. It's much easier for everyone involved if you say "I tried this, I got this output, and it's not right because... and so on." That's what Norm is saying. Don't try to solve the problem before you've found out what the problem is.
Mary Jane Sam
Greenhorn

Joined: Jul 15, 2008
Posts: 11
Thanks a lot for all your reply..

JDBC driver took care of automatic conversion of EBCDIC to corresponding codepage supported by the system. The packed decimal alone was converted properly (a few characters in one field received is packed decimal). The field received from mainframe DB2 is a combination of char and packed decimal and returned as a varchar field.

Since it was not possible to extract the actual value of packed decimal in this case, the DB2 person converted packed decimal to varchar before sending the data. This solved our problem..
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18150
    
    8

Yes, I have also found that zoned decimal survives that conversion as well. Unless the numbers are negative, in which case the bytes with the negative sign get converted to letters like J and K.
Kalpesh Soni
Ranch Hand

Joined: Jan 02, 2001
Posts: 311
http://www.coderanch.com/t/279125/Streams/java/ASCII-EBCDIC-conversion-preserving-COMP

cross referencing, because this implementation is more complete and this post comes first in google when you search packed decimal java

Nice job norm.


Test 094, IBM WID 6.0 cert
SCJP 1.2
SCBCD 1.3 Beta
SCWCD 1.4 Beta
SCMAD Beta
SCDJWS Beta

KS
Matt Flores
Greenhorn

Joined: May 05, 2010
Posts: 5
The code that Norm posted is great, however I ran into a snag, I was hoping to use this a function call to pass packed decimal data and return the decimal value. However when the passed argument has 0x00 bytes in the value the string argument is truncated from that point. Any one have ideas around this.

thanks,
Kalpesh Soni
Ranch Hand

Joined: Jan 02, 2001
Posts: 311
give me an exmple, how are you trying to use it
Matt Flores
Greenhorn

Joined: May 05, 2010
Posts: 5
using Norms code above I modified the mainline;

public static void main(String[] args) throws Exception {
byte[] pd = args[0] .getBytes();
System.out.println(PackedDecimal.parse(pd));

let us say we call this java code passing 0x0100561C as the value of the argurment. Since args is defined as a string and the second byte has a value of 0x00 args[0] gets a value of 0x01, the rest is truncated.

If the first byte is 0x00 then args[0] is a null string.

thanks,
Kalpesh Soni
Ranch Hand

Joined: Jan 02, 2001
Posts: 311
byte[] pd = args[0] .getBytes()

THIS is not the intended use

byte[] is supposed to represent the packed decimal internal representation in db2

did you even read the comments in his main?

byte[] pd = new byte[] {0x19, 0x2C}; // 192
this is not the same as "0x192C".getBytes()
Matt Flores
Greenhorn

Joined: May 05, 2010
Posts: 5
what is happeing here is that the packed decimal is chopped in bytes and passed as an array. If I do not have a byte that is x'00' then the code works perfectly. If the packed decimal is 0x11234D

byte[] pd = args[0] .getBytes() will build a byte array = {0x11, 0x23, 0x4D} this will result in -11234
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36563
    
  16
Welcome to the Ranch
Kalpesh Soni
Ranch Hand

Joined: Jan 02, 2001
Posts: 311
if args[0] is a String with value "0X11234D"

getBytes() will NOT build correct byte array

Why dont you give me the full content of your main, and tell me how you are executing it
Matt Flores
Greenhorn

Joined: May 05, 2010
Posts: 5
0x11234D is a representation only. what is passed is a 3 byte data x'11234D' run via jcl usng JZOS on the mainfraime. The representation is hexadecimal format. To evaluate the 3 byte data it is chr(17) - x'11' followed by chr(35)- x'23' then chr(78)- x'4D'. The problem is chr(0) which is the null character x'00' in both EBCDIC and ASCII. Strings are not able to handle this.

This is what the mainline code looks line. The characters may look different as the source in Unix System Sevices on Z/OS. Ý is [ and ¨ is ], the open and close square brackets shows differently.

public static void main(Stringݨ args) throws Exception {
byteݨ pd = argsÝ0¨.getBytes();
System.out.println(PackedDecimal.parse(pd));
}
} // end class


Part of the JCL
//JAVA EXEC PROC=JVMPRC60,
// ARGS=' *',
// JAVACLS='PackedDecimal'


the same JCL with HEX on to see the value of ARGS
//JAVA EXEC PROC=JVMPRC60,
66DCEC4CECC4DDDC7DEDDDCFF6444444444444
1111510575307963E15479360B000000000000
--------------------------------------
// ARGS=' *',
66444CDCE77013576444444444444444444444
110001972ED104CDB000000000000000000000
--------------------------------------
// JAVACLS='PackedDecimal'
66444DCECCDE77D88988C88898974444444444
110001151332ED7132544539413D0000000000

Looks funny because the font in this forum is proportional, if you are able to switch it to courier new it should line up.
The value being passed is x'0110345C'

The following is the proc that is being run

//JAVAJVM EXEC PGM=JVMLDM&VERSION,REGION=®SIZE,
// PARM='&LEPARM/&LOGLVL &JAVACLS &ARGS'
//STEPLIB DD DSN=&LIBRARY,DISP=SHR
//SYSPRINT DD SYSOUT=* < System stdout
//SYSOUT DD SYSOUT=* < System stderr
//STDOUT DD SYSOUT=* < Java System.out
//STDERR DD SYSOUT=* < Java System.err
//CEEDUMP DD SYSOUT=*
//ABNLIGNR DD DUMMY

this is similar to 'java PackedDecimal *' however, the argument being passed will very difficult to type. * in EBCIDIC is x'5C'.
Matt Flores
Greenhorn

Joined: May 05, 2010
Posts: 5
Kalpesh Soni wrote:if args[0] is a String with value "0X11234D"

getBytes() will NOT build correct byte array



I am assuming you are trying it using ASCII character set. If you pass a string value of "< +" this will tranlate to x'28207C'

< = 0x28
blank = 0x20
+ = 0x7C
Kalpesh Soni
Ranch Hand

Joined: Jan 02, 2001
Posts: 311
even if you provide the RIGHT string that represents a packed decimal

getBytes() will try to CHANGE it

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#getBytes()

Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.
The behavior of this method when this string cannot be encoded in the default charset is unspecified. The CharsetEncoder class should be used when more control over the encoding process is required.

so getBytes() will produce different bytes in windows US, windows chinese, Z-os etc

try writing the packed decimal bytes to a file, and read it as byte[] and unpack from java
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Packed decimal conversion - Java
 
Similar Threads
How can I convert Decimal value to Packed format
conversion from decimal to packed BCD
BCD to decimal and viceversa
ASCII TO EBCDIC conversion preserving COMP-3
How can I convert Decimal value to Packed Format