COMP3 Packed Decimals

Discussion in 'C Programming' started by RM, Nov 16, 2004.

  1. RM

    RM Guest


    I need to write a program that includes converting ASCII integers to
    COMP3 (Packed Decimal) format. Does anyone know of any C sample code
    on converting integers into COMP3 format?

    Thanks in advance.

    RM, Nov 16, 2004
    1. Advertisements

  2. RM

    Jack Klein Guest

    Since COMP3 is not something defined by the C language, there is no
    reason at all to assume that anyone reading this group has the
    faintest idea what it is.

    Have you tried something like typing the following into Google:

    "COMP 3" C source

    Try it, you might like it.
    Jack Klein, Nov 16, 2004
    1. Advertisements

  3. RM

    dandelion Guest

    Asking for a COBOL data-type on a C-froup does imply a fair amount of guts.
    I like that.
    dandelion, Nov 16, 2004
  4. RM

    RM Guest

    Hi, thanks for the response. Yes I did try it, all that came up was
    information on how to convert ASCII to COMP3 (not the other way
    around). 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.

    Thank you
    RM, Nov 16, 2004
  5. If you have code to do it one way round, then you can infer the code
    required to reverse that surely? After all, what you really need is the
    To find an algorithm, try comp.programming
    Yes, but your question is to do with the algorithm required. The language
    is irrelevant really.
    Mark McIntyre, Nov 16, 2004
  6. 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

    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."

    #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 */
    case '-':
    Sign = 0x0D;
    Text++; /* skip past sign character */

    /* 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

    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_
    Michael Wojcik, Nov 17, 2004
  7. Hello,

    This is a very complete answer to the OP, I just have some C style related
    I would pass BufSize as the second parameter to emphasize that it refers to
    Packed rather than Text.
    Although this expression is correct, it is advisable to put extra parens around
    *Text - '0' to avoid misinterpretation by the casual reader and extra warnings
    by the caution compiler fitted with defensive settings.

    Charlie Gordon, Nov 18, 2004
  8. I debated that myself. In the end I chose to go with this ordering
    because it's parallel to strncpy et al: destination, source, max
    bytes to copy. But I'm not wedded to it, and if there were more
    than these three parameters I'd put BufSize next to Packed.
    Yes, an extra set of parentheses wouldn't hurt there.

    (I haven't seen any reply from the OP. I wonder if he's still reading?)
    Michael Wojcik, Nov 19, 2004
  9. I suspected the infamous strncpy was the culprit.
    NEVER use strncpy
    don't model anything after that bastard
    it should be deprecated and removed from the standard.
    BAD BAD BAD strncpy

    Charlie Gordon, Nov 22, 2004
  10. Since the name of the function is Text To Packed, I would put the
    parameters in that order (Text, Packed, PackedBufSize). It gets very
    confusing maintaining code where the parameters are a different way
    round than the name implies.
    Oh yes, I know a lot of people who get the precedence of the shift
    operators wrong. Including me...

    Chris C
    Chris Croughton, Nov 22, 2004
  11. This style also has much to recommend it. Again, though, I chose to
    follow the order used by functions in the standard library. strxfrm,
    for example, puts the result in the first parameter.

    But as I noted in my response to Charlie, I'm not wedded to that
    order. And the standard library is no exemplar of consistency in
    this regard either, as the position of the FILE* argument in various
    stdio functions demonstrates. (Obviously it has to come before the
    variadic arguments for fprintf and fscanf; it would have been nice
    if fputs and the like also had made it the first parameter. Perhaps
    they antedate the formatting functions?)
    Michael Wojcik, Nov 24, 2004
  12. The str... functions in general do have the first parameter being
    'output' (where they have output), they are internally consistent.
    However, they have names which don't necessarily imply any ordering
    (strcpy, strcat, etc.), except that where the parameters are different
    types in some cases they do imply the correct ordering (I remember which
    way round strchr(a,b) is because of the name, strchr(str, chr)).
    File operations don't work well with either rule ("input, output" or
    "output, input"), otherwise they would need to something silly like

    fread(FILE*, void*, size_t)
    fwrite(void*, size_t, FILE*)

    I think they were invented in different places, from what I can remember
    back that far. The Unix read() and write() functions have the fd first
    (and that's logical to me, it's something which is very closely related
    to the action, as in "write to this file" being effectively a single
    action), they came before the file stream functions. Quite why the
    fread/fwrite put them at the end I don't remember hearing, I just cursed
    it (and still curse it, it's not logical, Jim!), fseek got the same
    order as lseek.

    I have difficulty in general making up names for things with the output
    first. That's probably a limitiation in my imagination, not a general
    criterion, but I find "stringToInt()" to be more intuitive than
    "intFromString()". But either is much better than "convert(a,b)" where
    the order isn't implied at all...

    Chris C
    Chris Croughton, Nov 25, 2004
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.