This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Long Hex ASCII string to decimal ASCII


Using the C51 tools, I am trying to convert a long Hex number, entered as an ASCII string, to its decimal equivalent.
For example:
the string could be:
"ABCDEF1234565"
And I would need to convert to the string:
"188900967593046"

The problem I have found is that since there does not seem to be a true 'double' variable type, I cannot do a direct conversion of the number. Which would consist of converting the ASCII hex to a variable, and then printing it out as decimal.

I have tried several methods, but cannot get past needing variable storage larger than 32bits.

Any suggestions on how to achieve this would be greatly appreciated...

Thanks!

David Marten

Parents
  • On Nov. 11, 2001, I sent in a C51 V6.20 bug report via e-mail to support.us@keil.com. I never received a response, so assumed Keil's policy was to silently introduce the bug fix in a subsequent update. After downloading V6.21, I see that the bug is still present. Now I'm wondering whether my e-mailed bug report was ever acted upon, so I'm going to try the forum as the means to report the bug.<br>
    <br>
    I have a section of code with pointer incrementation that compiles and executes correctly when the pointer is defined as a generic pointer or as an xdata pointer, or when the optimization setting is reduced from the default OT(8,SPEED) to OT(7,SPEED). However, when the pointer is defined as a data or idata pointer, the compiler does not emit code to increment the pointer with default optimization.<br>
    <br>
    I have provided example code demonstrating the problem. The specific statement is line 50 below.<br>
    <br>

    unsigned char idata u64[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    unsigned char idata s[21];
    
    void U64ToStr( char idata *s, unsigned char idata *binP, unsigned char n )
    {
        unsigned char        bcd;
        unsigned char idata *bcdP;
        unsigned char        bitMsk = 0x80;
        unsigned char        carry;
        unsigned char        i;
    
        /*  Zero the target buffer (NUL-terminating the string).
         */
        for (bcdP = s, i = n + 1; i != 0; *bcdP++ = 0, i--)
            ;
    
        /*  Convert 64 bits of binary to unpacked BCD.  For each bit, starting
         *  with the MSBit, BCD = (BCD * 2) + bit.
         */
        for (i = 64; i != 0; i--)
        {
            carry = (*binP & bitMsk) ? 1 : 0;
    
            for (bcdP = s + n; bcdP != s; /* Iter in body */)
            {
                bcd  = *--bcdP * 2;
                bcd += carry;
    
                if (bcd < 10)
                    carry = 0;
                else
                {
                    carry = 1;
                    bcd  -= 10;
                }
    
                *bcdP = bcd;
            }
    
            if ((bitMsk >>= 1) == 0)
            {
                bitMsk = 0x80;
                binP++;
            }
        }
    
        /*  ASCII'fy BCD.
         */
        for (i = n; i != 0; i--)
            *bcdP++ += '0'; /* <-- C51 BUG: bcdP doesn't increment for (i)data */
    }
    
    void main( void )
    {
        for (;;)
            U64ToStr( s, u64, 6 );
    }
    
    <br>
    --Dan Henry<br>

Reply
  • On Nov. 11, 2001, I sent in a C51 V6.20 bug report via e-mail to support.us@keil.com. I never received a response, so assumed Keil's policy was to silently introduce the bug fix in a subsequent update. After downloading V6.21, I see that the bug is still present. Now I'm wondering whether my e-mailed bug report was ever acted upon, so I'm going to try the forum as the means to report the bug.<br>
    <br>
    I have a section of code with pointer incrementation that compiles and executes correctly when the pointer is defined as a generic pointer or as an xdata pointer, or when the optimization setting is reduced from the default OT(8,SPEED) to OT(7,SPEED). However, when the pointer is defined as a data or idata pointer, the compiler does not emit code to increment the pointer with default optimization.<br>
    <br>
    I have provided example code demonstrating the problem. The specific statement is line 50 below.<br>
    <br>

    unsigned char idata u64[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
    unsigned char idata s[21];
    
    void U64ToStr( char idata *s, unsigned char idata *binP, unsigned char n )
    {
        unsigned char        bcd;
        unsigned char idata *bcdP;
        unsigned char        bitMsk = 0x80;
        unsigned char        carry;
        unsigned char        i;
    
        /*  Zero the target buffer (NUL-terminating the string).
         */
        for (bcdP = s, i = n + 1; i != 0; *bcdP++ = 0, i--)
            ;
    
        /*  Convert 64 bits of binary to unpacked BCD.  For each bit, starting
         *  with the MSBit, BCD = (BCD * 2) + bit.
         */
        for (i = 64; i != 0; i--)
        {
            carry = (*binP & bitMsk) ? 1 : 0;
    
            for (bcdP = s + n; bcdP != s; /* Iter in body */)
            {
                bcd  = *--bcdP * 2;
                bcd += carry;
    
                if (bcd < 10)
                    carry = 0;
                else
                {
                    carry = 1;
                    bcd  -= 10;
                }
    
                *bcdP = bcd;
            }
    
            if ((bitMsk >>= 1) == 0)
            {
                bitMsk = 0x80;
                binP++;
            }
        }
    
        /*  ASCII'fy BCD.
         */
        for (i = n; i != 0; i--)
            *bcdP++ += '0'; /* <-- C51 BUG: bcdP doesn't increment for (i)data */
    }
    
    void main( void )
    {
        for (;;)
            U64ToStr( s, u64, 6 );
    }
    
    <br>
    --Dan Henry<br>

Children