Packed Decimal - Zoned Format - Cobol Comp-3 - Room 42 Computers & The Internet Resource Center
For Your Information - IBM Cobol USAGE COMP-3 is equivalent to packed decimal.
The steps to follow in converting comp-3 (packed decimal) in an EBCDIC file to ASCII format would be dependent on whether you have some machines to help you. In general, you will need to:
Because I don't know what you have to work with, machine and compiler wise, let me describe what would be ideal.
- Identify the bytes that are Comp-3 (packed decimal) in the EBCDIC file
- Convert the Comp-3 (packed decimal) to a decimal integer zoned format - note: this will occupy more bytes then the original Comp-3 (packed decimal) does
- Convert the EBCDIC zoned format decimal integer to ASCII on a byte for byte basis.
With the file on the IBM mainframe, write a simple little COBOL or Assembler program to perform step 2 above. The program would do no more then read the file in the format it is in, and write the file back out - except no Comp-3 (packed decimal). Those fields would be written out decimal integer zoned format - or just normal, would be another way of wording it.
Step 3 can be performed on any machine, again by reading the file in and writing it back out again. I have both Java and C examples of the EBCDIC to ASCII conversion routines (or vice versa) posted on the web at http://www.room42.com/store/computer_center/java_translate.shtml and http://www.room42.com/store/computer_center/c_translate.shtml
If you do not have access to a IBM mainframe for the step 2 conversion process, the whole job becomes more difficult. A Comp-3 (packed decimal) byte is actually made up of 2 separate 4 bit numerical digits, with the last or right most byte being even more complex, in that the upper 4 bits are that numerical digit and the lower 4 bits are the sign. You will have to write some specialized code, if the step 2 conversion has to be done on a ASCII machine.
If you just need details on the "COBOL Data Division--Data Description"s. IBM has their books posted on the web these days. I looked up COBOL Data Division--Data Description for you. It's located at http://publib.boulder.ibm.com:80/cgi-bin/bookmgr/BOOKS/IGYVR002/CCONTENTS You may have to hunt around a little, but you should come close. Note that in COBOL the abbreviation PIC refers to the PICTURE Clause
A popular question this week has been from those whiz bang guru bit heads asking about how to convert EBCDIC floating point to ASCII. Sheesh! Not as easy as it might sound. So I'm going to refer those off to the IBM Principles of Operations Manual. It's located at http://publib.boulder.ibm.com:80/cgi-bin/bookmgr/BOOKS/DZ9AR006/CCONTENTS Happy Hunting.
Wishing you all luck in your endevors.
I hope this helps. Let me know.
regards,
Linda
© copyright IBM, reprinted with permission from the IBM Principles of Operations Manual
Decimal integers consist of one or more decimal digits and a sign. Each digit and the sign are represented by a 4-bit code. The decimal digits are in binary-coded decimal (BCD) form, with the values 0-9 encoded as 0000-1001. The sign is usually represented as 1100 (C hex) for plus and 1101 (D hex) for minus. These are the preferred sign codes, which are generated by the machine for the results of decimal-arithmetic operations. There are also several alternate sign codes (1010, 1110, and 1111 for plus; 1011 for minus). The alternate sign codes are accepted by the machine as valid in source operands but are not generated for results.
Decimal integers may have different lengths, from one to 16 bytes. There are two decimal formats: packed and zoned. In the packed format, each byte contains two decimal digits, except for the rightmost byte, which contains the sign code in the right half. For decimal arithmetic, the number of decimal digits in the packed format can vary from one to 31. Because decimal integers must consist of whole bytes and there must be a sign code on the right, the number of decimal digits is always odd. If an even number of significant digits is desired, a leading zero must be inserted on the left.
In the zoned format, each byte consists of a decimal digit on the right and the zone code 1111 (F hex) on the left, except for the rightmost byte where the sign code replaces the zone code. Thus, a decimal integer in the zoned format can have from one to 16 digits. The zoned format may be used directly for input and output in the extended binary-coded-decimal interchange code (EBCDIC), except that the sign must be separated from the rightmost digit and handled as a separate character. For positive (unsigned) numbers, however, the sign can simply be represented by the zone code of the rightmost digit because the zone code is one of the acceptable alternate codes for plus.
In either format, negative decimal integers are represented in true notation with a separate sign. As for binary integers, the radix point (decimal point) of decimal integers is considered to be fixed at the right, and any scaling is done by the programmer.
The following are some examples of decimal integers shown in hexadecimal notation:
Decimal Value Packed Format Zoned Format +123 12 3C F1 F2 C3 or or 12 3F F1 F2 F3 -4321 04 32 1D F4 F3 F2 D1 +000050 00 00 05 0C F0 F0 F0 F0 F5 C0 or or 00 00 05 0F F0 F0 F0 F0 F5 F0 -7 7D D7 00000 00 00 0C F0 F0 F0 F0 C0 or or 00 00 0F F0 F0 F0 F0 F0
/** * @author Linda Fisher linda@room42.com * @version 1.0 31 Dec 1998 */ import java.util.*; import java.io.*; public final class HexByte { private static File input_file; private static FileInputStream input; private static File output_file; private static FileOutputStream output; private static byte hexbyte; /** * Description: base 10 int changed to two 4 bit BitSet's * @param byte the byte the BitSet's are to be created from * @return BitSet[] the BitSet's created from the byte * @exception */ private final static BitSet[] bitSetsFromBase10(byte hi) { BitSet bits[] = new BitSet[2]; bits[0] = new BitSet(4); bits[1] = new BitSet(4); int bb = new Integer(hi).intValue(); int m7 = bb / 128; bb = (bb-(m7*128)); if (m7 > 0) { bits[0].set(3); } int m6 = bb / 64; bb = (bb-(m6*64)); if (m6 > 0) { bits[0].set(2); } int m5 = bb / 32; bb = (bb-(m5*32)); if (m5 > 0) { bits[0].set(1); } int m4 = bb / 16; bb = (bb-(m4*16)); if (m4 > 0) { bits[0].set(0); } int m3 = bb / 8; bb = (bb-(m3*8)); if (m3 > 0) { bits[1].set(3); } int m2 = bb / 4; bb = (bb-(m2*4)); if (m2 > 0) { bits[1].set(2); } int m1 = bb / 2; bb = (bb-(m1*2)); if (m1 > 0) { bits[1].set(1); } int m0 = bb; if (m0 > 0) { bits[1].set(0); } return(bits); } /** * Description: bit settings changed to base 10 * @param BitSet the BitSet the decimal integer is to be created from * @return bb the int created from the BitSet * @exception */ private final static int intBase10FromBitSet(BitSet bs) { // bit settings changed to base 10 boolean m0 = bs.get(0); boolean m1 = bs.get(1); boolean m2 = bs.get(2); boolean m3 = bs.get(3); int bb = 0; if (m0) { bb = bb + 1; } if (m1) { bb = bb + 2; } if (m2) { bb = bb + 4; } if (m3) { bb = bb + 8; } return(bb); } /** * Description: bit settings changed to base 10 * @param BitSet the BitSet the zoned format decimal integer is to be created from * @return bb the int created from the BitSet * @exception */ private final static int intBase10ZonedFromBitSet(BitSet bs) { boolean m0 = bs.get(0); boolean m1 = bs.get(1); boolean m2 = bs.get(2); boolean m3 = bs.get(3); int bb = 0; if (m0) { bb = bb + 1; } if (m1) { bb = bb + 2; } if (m2) { bb = bb + 4; } if (m3) { bb = bb + 8; } if (bb < 10) { bb = bb + 240; } else if (bb == 10) { /* positive */ bb = bb + 240; } else if (bb == 11) { /* negative */ bb = bb + 208; } else if (bb == 12) { /* positive */ bb = bb + 240; } else if (bb == 13) { /* negative */ bb = bb + 208; } else if (bb == 14) { /* positive */ bb = bb + 240; } else if (bb == 15) { /* positive */ bb = bb + 240; } return(bb); } public static void main(String args[]) { try { input_file = new File("input.file"); input = new FileInputStream(input_file); output_file = new File("output.file"); output = new FileOutputStream(output_file); } catch (Exception e) { System.out.println("Something went wrong with the files " + e); } try { /* simple 16 bit - 2 bytes packed decimal converted to zoned format decimal integer */ /* 123C (positive) converted to F1F2 F3 or 123D (negitive) converted to F1F2 D3 */ toZoned(); withSign(); } catch (Exception e) { System.out.println("Something went wrong with reading the file " + e); } } private static byte readByte() throws IOException { int ch = input.read(); if (ch < 0) throw new EOFException(); return (byte)(ch); } /** * Description: both sets of 4 bits in an 8 bit byte converted to zoned format decimal integer */ private static void toZoned() throws IOException { hexbyte = readByte(); BitSet these_bits[] = bitSetsFromBase10(hexbyte); int b1 = intBase10ZonedFromBitSet(these_bits[0]); output.write(b1); int b2 = intBase10ZonedFromBitSet(these_bits[1]); output.write((int)b2); } /** * Description: left most 4 bits in an 8 bit byte converted to zoned format decimal integer * right most 4 bits in an 8 bit byte converted to zoned format sign */ private static void withSign() throws IOException { hexbyte = readByte(); System.out.println("Read in byte " + hexbyte); BitSet those_bits[] = bitSetsFromBase10(hexbyte); int b1 = intBase10FromBitSet(those_bits[0]); int b2 = intBase10FromBitSet(those_bits[1]); System.out.println(b1 + " sign byte is " + b2); if (b2 == 10) { /* positive */ b1 = b1 + 240; } else if (b2 == 11) { /* negative */ b1 = b1 + 208; } else if (b2 == 12) { /* positive */ b1 = b1 + 240; } else if (b2 == 13) { /* negative */ b1 = b1 + 208; } else if (b2 == 14) { /* positive */ b1 = b1 + 240; } else if (b2 == 15) { /* positive */ b1 = b1 + 240; } output.write((int)b1); } }
Buy Your Next Book From Amazon.com Through Us. |
|
Room 42:  What about the 42?