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

char to unsigned int

Hi all

Here is some code

char prev_ch;
unsigned int chksum_read;

chksum_read += (WORD)prev_ch*256;
chksum_read += (unsigned int)prev_ch<<8;

if prev_ch has a value of 0xDB after one of of the two above statments cheksum_read is 0xDA00 instead of 0xDB00. Can anyone explain where I am going wrong?

Parents
  • I second Andrew's suggestion. I'd add that you should never trust the implicit signed-ness of the bare "char" declaration, since it varies from compiler to compiler. "U8" is also useful as it clearly makes the distinction between a variable intended as a small integer and a variable intended as human-readable text (a "character").

    Do you mean that both forms of the statement posted produce the same result? Or that one produces the expected result and one does not? (If so, which one works?)

    The snippet as shown does not initialize chksum_read, so the += leaves you at the mercy of whatever garbage was in the variable. If that happened to be 0xFF00, you would see the described results.

    Assuming we're talking about the 8051, if you are going to do a lot of shift by 8s, you might consider a union type.

    typedef struct
        {
        U8 byte[2];
        U16 u16;
        } BytewiseU16;
    
    U8 prev_ch;
    Bytewise16 chksum_read;
    
    // shift left by 8
    chksum_read.byte[0] = chksum_read.byte[1];
    chksum_read.byte[1] = 0;
    
    // add prev_ch shifted left by 8
    chksum_read[0] += prev_ch;
    

    It's a little ugly and non-portable to different endian systems, but will save you some time and code space if that's important.

Reply
  • I second Andrew's suggestion. I'd add that you should never trust the implicit signed-ness of the bare "char" declaration, since it varies from compiler to compiler. "U8" is also useful as it clearly makes the distinction between a variable intended as a small integer and a variable intended as human-readable text (a "character").

    Do you mean that both forms of the statement posted produce the same result? Or that one produces the expected result and one does not? (If so, which one works?)

    The snippet as shown does not initialize chksum_read, so the += leaves you at the mercy of whatever garbage was in the variable. If that happened to be 0xFF00, you would see the described results.

    Assuming we're talking about the 8051, if you are going to do a lot of shift by 8s, you might consider a union type.

    typedef struct
        {
        U8 byte[2];
        U16 u16;
        } BytewiseU16;
    
    U8 prev_ch;
    Bytewise16 chksum_read;
    
    // shift left by 8
    chksum_read.byte[0] = chksum_read.byte[1];
    chksum_read.byte[1] = 0;
    
    // add prev_ch shifted left by 8
    chksum_read[0] += prev_ch;
    

    It's a little ugly and non-portable to different endian systems, but will save you some time and code space if that's important.

Children