jdm1@eds1.UUCP (Jon McCown) (06/21/89)
I am looking for routines to munge IBM/370 style packed decimal data into a long (or int) and vice versa. ptol or ltop anyone? Range checking is not a major concern (yet). My work on the problem has produced some medium kludgy and slow routines that have yet to be proven reliable. Surely someone has an elegant (or at least well tested) shot at this. . . . ? - Jon McCown (No, I don't have a COBOL compiler on the system :-) -- J.D. McCown - RCSG Director - Senate of Pennsylvania psuvax1!eds1!jdm1 (this space intentionally "Your life or your lupins!" jdm1@eds1.eds.com filled with this text) - Dennis Moore
abbadon@nuchat.UUCP (David Neal) (06/29/89)
#include <stdio.h> /* Routine to unpack BCD packed decimal into an integer. */ unpack(packed, length, unpacked) char packed[]; /* Array of chars containing packed number */ int length; /* Length of the array (not '\0' terminated) */ int *unpacked; /* Pointer to integer for return value */ { register int i, j; static char asciibuf[128]; /* Number cannot be > 63 digits in length */ j = 0; length--; /* Decrement length; we always use length - 1 because of the special case and because of 'C' array indices start at 0. */ /* Run to length-1 bytes; last byte is a special case */ for ( i = 0; i < length; i++ ) { asciibuf[j++] = ( (packed[i] & 0xf0) >> 4 ) + 0x30; asciibuf[j++] = (packed[i] & 0x0f) + 0x30; /* 0x30 is the delta between BCD nybble x and it's ascii counterpart. */ } asciibuf[j++] = ( (packed[length] & 0xf0) >> 4 ) + 0x30; asciibuf[j] = '\0'; fprintf(stderr, "unpack: %s \n", asciibuf); *unpacked = atoi(asciibuf); /* Special case: If the last nybble is 0x0d, the number is negative */ if ( (packed[length] & 0x0f) == 0x0d ) *unpacked *= -1; } Sorry about the wasted bandwith; this guys mail bounces and he's tough to get on the phone! Please no flamage about system dependant this or messy that; it's just a quick hack to help the guy. David Neal abbadon@nuchat.UUCP uunet!nuchat!abbadon killer!texbell!nuchat!abbadon