... Do you have a recommendation as to which group might be a
better target? I assumed this would be the best because it is
regarding C programming and the group name is comp.lang.c.
It's not really a C programming question, as stated. A C programming
question would be something like:
Here's a data format, packed decimal, as defined by the COBOL
COMP-3 data type. I need to convert some integers in string
representation [are they actually in ASCII, or are they in the
implementation character set, which might or might not be ASCII?]
into this form. What's a good way to do that in C?
You still might have been pointed to comp.programming on the grounds
that this is as much an algorithm question as a C programming one,
but it's closer.
Since you didn't explain what COMP-3 is (aside from stating that it's
also called packed decimal), and since COMP-3 isn't defined by C, the
question wasn't relevant to C as such.
Now, since COMP-3 *is* defined by COBOL, comp.lang.cobol would have
been a possible starting place.
All that said, let me rephrase your question and provide some
assistance:
COMP-3, aka IBM packed decimal, is an integer data representation.
It places one decimal digit in each of the successive four-bit groups
of a sequence of octets. The digits are placed in "big-endian" order,
with the most significant decimal digit in the most significant four
bits of the octet at the lowest memory address. The final four bits
of the final octet are a sign indicator: 0xC for positive, 0xD for
negative, and 0xF for unsigned. If there are an even number of
decimal digits, the packed representation has four padding bits of 0
in the high end of the first octet.
Marginally tested sample C code to convert a text representation of an
integer to packed decimal:
/* This code only works with 8-bit bytes. See if this implementation
is suitable. */
#include <limits.h>
#if CHAR_BIT != 8
#error "This code requires 8-bit bytes."
#endif
#include <string.h>
#include <stddef.h>
/* Convert text-representation integers to packed-decimal representation.
The text representation must be a sequence of decimal digits, with an
optional leading sign; if no sign character is present, the packed-
decimal representation is marked as unsigned. The packed-decimal
representation is placed in a caller-supplied buffer.
Returns 0 on errors, and the length of the packed representation on
success. */
size_t TextToPacked(unsigned char *Packed, const char *Text, size_t BufSize)
{
char Sign = 0x0F;
size_t Digits;
unsigned char *PkdPtr = Packed;
/* Validate parameters */
if (! Packed || ! Text)
return 0;
/* Check for a sign character */
switch (*Text)
{
case '+':
Sign = 0x0C;
Text++; /* skip past sign character */
break;
case '-':
Sign = 0x0D;
Text++; /* skip past sign character */
break;
}
/* Count the number of digits to see if we need to pad or if the
destination is too small. */
Digits = strlen(Text);
/* Number of destination bytes needed: digits, plus sign, plus padding
if required, all divided by two. */
if ((Digits + 1 + !(Digits%2))/2 > BufSize)
return 0;
/* Make sure the text string is well-formed. */
if (Digits < 1 || Digits != strspn(Text, "0123456789"))
return 0;
/* If there is an even number of digits, convert the first digit and
place it in the first packed byte with four bits of padding. This
reduces the even-digit case to the odd-digit case. */
if (! (Digits % 2))
*PkdPtr++ = *Text++ - '0';
/* Convert the remaining digits two at a time, except for the last. */
while (Text[1])
{
*PkdPtr = (Text[0] - '0') << 4 | (Text[1] - '0');
PkdPtr += 1;
Text += 2;
}
/* Convert the final remaining digit and the sign. */
*PkdPtr++ = (*Text - '0' << 4) | Sign;
return PkdPtr - Packed;
}
Give that a shot.
--
Michael Wojcik (e-mail address removed)
Unlikely predition o' the day:
Eventually, every programmer will have to write a Java or distributed
object program.
-- Orfali and Harkey, _Client / Server Programming with Java and CORBA_