home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
packdec.zip
/
PD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-01
|
5KB
|
155 lines
/*
Packed Decimal, Binary Conversion
Copyright (c) 1994, Iambic Software, Inc.
All rights reserved
*/
#include <mem.h>
#include "pd.h"
short int sPackedToBin( unsigned char *pPack, long *lBin, short nLen )
{
/************************************************************
Name: sPackedToBin
Function:
This routine will convert IBM 370 packed dicimal numbers to fixed
point binary numbers four bytes long.
arguments:
1. unsigned char pointer to the packed decimal number, max length
is six bytes.
2. pointer to a long int to receive the result.
3. short int length of argument 1, the packed decimal number.
return codes:
0 success
1 invalid decimal digit
2 overflow, numbers greater than 2,147,483,647 (0x7fffff)
3 invalid length specified
*************************************************************/
short int iI; /* loop index */
unsigned short int iFirstNib; /* first nibble */
unsigned short int iLastNib; /* last nibble */
long int lTBin; /* binary work */
unsigned char *pWork; /* work pointer for packed number */
if ( nLen > 6 || nLen < 1 ) /* validate length */
return( 3 );
lTBin = 0; /* initialize work number */
pWork = pPack; /* copy pointer to work */
for( iI = 1; iI <= nLen; iI++ )
{
iFirstNib = ( *pWork & 0xf0 ) >> 4; /* obtain high order 4 bits */
iLastNib = *pWork & 0x0f; /* obtain low order 4 bits */
if ( iFirstNib > 0x90 ) /* check first nibble */
return( 1 );
if ( iI != nLen ) /* is this the last byte ? */
{
if ( iLastNib > 9 ) /* last nibble digit ok ? */
return( 1 );
}
else
{
if ( iLastNib < 10 ) /* last nibble of number, for sign */
return( 1 );
}
lTBin *= 10; /* shift one digit to left */
lTBin += iFirstNib; /* add in the next number */
if ( lTBin < 0 ) /* number has overflowed */
return(2);
if ( iI != nLen ) /* last byte, dont add sign */
{
lTBin *= 10; /* shift one byte to the left */
lTBin += iLastNib; /* add in the next number */
if ( lTBin < 0 ) /* number has overflowed */
return(2);
}
pWork++; /* point to the next output byte */
}
switch ( iLastNib ) /* make negative if needed */
{
case 0x0b: /* negative decimal signs ? */
case 0x0d:
lTBin *= -1; /* make the number negative */
break;
}
*lBin = lTBin; /* return the result to the source field */
return( 0 );
}
/************************************************************
Name: sBinToPacked
Function:
This routine will convert long binary number to IBM 370 packed
decimal format eight bytes long.
arguments:
1. unsigned char pointer to the packed decimal number result
8 bytes long
2. pointer to a long int to convert.
return codes:
0 success
*************************************************************/
short int sBinToPacked( unsigned char *pPack, long *lBin )
{
unsigned char *pPkd; /* working pointer for packed numb */
long lWBin; /* working binary number */
unsigned char Pkd[8]; /* work packed number */
short iRem; /* remainder (may cause warnings
abound significant digits during
compile ) */
short iI; /* loop counter */
lWBin = *lBin; /* copy input */
memset( Pkd, 0, 8); /* clear number */
pPkd = Pkd + 7; /* point to last byte of packed num */
if ( lWBin < 0 ) /* is number negative */
{
*pPkd |= 0x0d; /* move in negative sign */
lWBin *= -1; /* make it positive */
}
else
*pPkd |= 0x0c; /* move in positive sign */
iRem = lWBin % 10; /* get ones digit */
*pPkd |= iRem << 4; /* add digit to number */
lWBin /= 10; /* divide by 10 */
for ( iI=1 ; iI < 8 ; iI++ ) /* setup loop for remainder of digits */
{
pPkd--; /* move pointer one left */
if ( ! lWBin ) /* no more digits, exit */
break;
iRem = lWBin % 10; /* get next digit */
*pPkd |= iRem; /* add digit to packed number */
lWBin /= 10; /* divide number by 10 */
if ( ! lWBin ) /* no more digits, exit */
break;
iRem = lWBin % 10; /* get next digit */
*pPkd |= iRem << 4; /* add digit to paced number */
lWBin /= 10; /* divide number by 10 */
}
memmove( pPack, Pkd, 8); /* return number to target field */
return( 0 );
}