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.

Question: How do I convert comp3 data in ebcdic file to ascii format?

Answer:

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:

  1. Identify the bytes that are Comp-3 (packed decimal) in the EBCDIC file
  2. 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
  3. Convert the EBCDIC zoned format decimal integer to ASCII on a byte for byte basis.
Because I don't know what you have to work with, machine and compiler wise, let me describe what would be ideal.

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
 

Sample Java code to convert packed decimal comp-3 to zoned format decimal integer

/**
  * @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);
    }
}

Help Keep This Site Live.
Buy Your Next Book From Amazon.com Through Us.

The Computer Top 50
Computers & Internet
For Techie's
Troubleshooting
Algorithms
Object Oriented
CORBA

TCP/IP
Cisco Routers
Network Hardware
LAN
Network Security
Novell Netware
ISDN
Database Management
Database Design
Web Database
Object Databases
Distributed Databases
Data Warehousing
Oracle
Microsoft Access
PC Upgrade
MCSE
Visual Basic
Windows '98
Web Design

ASCII to EBCDIC to BINARY Code Tables

In Association with Amazon.com

Room 42:  What about the 42?

Click Here to send me an Email / Feedback
Copyright © 1996-2006 by Room 42 Software, LLC. All rights reserved.