Numeric data conversion considerations

Data conversion is not only concerned with the representation of character data. The method of storing numbers can vary among different hardware platforms. This means that conversion routines might be required in order to convert numerical (binary) data that is received from a remote system into the local machine format.

As an example, Figure 1 shows how some of the standard C language data types are represented on the RS/6000®, HP 9000 Series 800 computers, and Intel computers.

The major difference between the two representations that are shown is the byte ordering. The decimal value 550 is stored as 0x0226 on the RS/6000, HP 9000 Series 800 and HP-UX IPF computers, and SPARC machines. These machines use the big-endian format for numbers, where the most significant byte of the number is stored in the lower machine address and the least significant byte is stored in the higher machine address. IBM® mainframes are also big-endian machines.

On the Intel computers, the bytes are reversed, so decimal 550 is stored as 0x2602. This format is called little-endian.

Figure 1. Representation of numbers
Representation of numbers on an IBM RISC System/6000, HP9000 Series 800 
and HP-UX IPF Computer, SNI Series, and SPARC machines
C Data type                 Value  Size(bytes)   Represented as:  
unsigned short int          550        2           02 26  
short int                   550        2           02 26
short int                  -550        2           FD DA  
unsigned long int        555550        4           00 08 7A 1E
long int                 555550        4           00 08 7A 1E
long int                -555550        4           FF F7 85 E2
unsigned int                550        4           00 00 02 26
int                         550        4           00 00 02 26
int                        -550        4           FF FF FD DA
Representation of numbers on  Digital Alpha machines
C Data type                 Value  Size(bytes)   Represented as:
unsigned short int          550         2          26 02
short int                   550         2          26 02
short int                  -550         2          DA FD
unsigned long int        555550         8          1E 7A 08 00 00 00 00 00
long int                 555550         8          1E 7A 08 00 00 00 00 00
long int                -555550         8          E2 85 F7 FF FF FF FF FF 
unsigned int                550         4          26 02 00 00
int                         550         4          26 02 00 00
int                        -550         4          DA FD FF FF
Representation of numbers on Intel machines

C Data type                 Value  Size(bytes)    Represented as:

unsigned short int           550           2          26 02  
short int                    550           2          26 02
short int                   -550           2          DA FD  
unsigned long int         555550           4          1E 7A 08 00  
long int                  555550           4          1E 7A 08 00  
long int                 -555550           4          E2 85 F7 FF  
unsigned int                 550           4          26 02 00 00  
int                          550           4          26 02 00 00
int                         -550           4          DA FD FF FF

If numerical data is sent between two machines that use different byte ordering, either the sender or receiver must swap the bytes around so that the data is correctly interpreted by the receiving system. In most cases, CICS® can be configured to do this byte swapping automatically. However, you might need to include byte-swapping functions in the user exit for function shipping (refer to Coding a nonstandard data conversion program), and transaction routing (refer to Writing your own version of DFHTRUC).

Figure 2 and Figure 3 show two example C functions that can be used for halfword and fullword byte swapping. The first swaps the bytes for a two-byte number such as a short int, and the second swaps the bytes for a four-byte number such as an int. Any byte-swapping routine must be aware of the number of bytes that are used to store a number. Therefore, refer to your programming language documentation to check the sizes of the data types that your programs use.
Figure 2. Sample C function for halfword swap
   
/*  
*-  
* Halfword (2 byte) Byte Swap  
*-  
*/
 void HalfWord_ByteSwap(void  *Buffer) 
 {     
    register unsigned char    SavedByte;           /* temp variable */
    unsigned char            *BufferPtr = Buffer;  /* temp pointer */ 
     /*      
      * Save the first byte into the temporary buffer,      
      * move the second byte to the first byte position      
      * and finally put the saved first byte into the      
      * second byte position.      
      */       
     SavedByte = *BufferPtr;     
     *BufferPtr = *(BufferPtr+1);     
     *(BufferPtr+1) = SavedByte;
      return; 
}   
Figure 3. Sample C function for fullword swap
 
/*
 *-----------------------------------------------------------------
 * Fullword (4 byte) Byte Swap
 *-----------------------------------------------------------------
 */
 
void FullWord_ByteSwap(void    *Buffer)
{
    register unsigned char    SavedByte;          /* temp variable */
    unsigned char            *BufferPtr = Buffer; /* temp pointer */
 
    /*
     * Save the first byte into the temporary buffer,
     * move the fourth byte to the first byte position
     * and finally put the saved first byte into the
     * fourth byte positi  on.
     */
 
    SavedByte = *BufferPtr;
    *BufferPtr = *(BufferPtr+3);
    *(BufferPtr+3) = SavedByte;
 
    /*
     * Save the second byte into the temporary buffer,
     * move the third byte to second byte position
     * and finally put the saved second byte into the
     * third byte position.
     */
 
    SavedByte = *(BufferPtr+1);
    *(BufferPtr+1) = *(BufferPtr+2);
    *(BufferPtr+2) = SavedByte;
 
    return;
}
 

The machine hardware and operating system can also affect the size of a data type. Variations exist in the size of the long data type. It is four bytes on the RS/6000, HP 9000 Series 800 computers, Intel computers, and SPARC machines. If you are sending numerical data between different types of machine, choose data types that are the same size on both machines to simplify the data conversion. The CICS standard data types in prodDir/include/cicstype.h provide C language data types that are the same size for all CICS workstation products.

Finally, if the data that your programs send is defined in a record structure, your data conversion routines must handle the padding that can be automatically inserted into the structure to maintain boundary alignment. For example, consider the record structure that is shown in Figure 4, which is defined in the C language. It contains a one-byte character (OneByteCharacter), a four-byte integer (FullWordInteger), another one-byte character (AnotherCharacter) and finally a two-byte integer (HalfWordInteger).
Figure 4. Example record structure
 
    struct
    {
      char       OneByteCharacter;
      int        FullWordInteger;
      char       AnotherCharacter;
      short int  HalfWordInteger;
    } ExampleRecord;
 

Although only eight bytes of storage have been defined, the structure actually takes up 12 bytes. Three bytes are inserted after OneByteCharacter so FullWordInteger starts on a fullword boundary and an additional byte is inserted after AnotherCharacter, so HalfWordInteger starts on a halfword boundary.