On Wed, 4 May 2011, stof...@skulp.net wrote:
> Hi, I have to transmit an unsigned long as four bytes, so I split them up > and join them again, but with the folowing example code, I get overflow at > long_counter>32767 - can any of you give me a clue how to do it right? > // split long_counter to four unsigned char's > for (i = 0; i < 4; i++) { > char_counter[i] = (long_counter & (0xff << (i * 8))) >> (i * 8); > } > > // convert them to unsigned int again > long_counter = char_counter[0] | (char_counter[1] << 8) | > (char_counter[2] << 16) | (char_counter[3] << 24); > Your code for splitting the long into chars should work, but SDCC can optimize this much better: char_counter[0] = long_counter; char_counter[1] = long_counter >> 8; char_counter[2] = long_counter >> 16; char_counter[3] = long_counter >> 24; The problem you are having putting them back together is due to the C integer promotion rules. Although you store the final result into a variable of type long, all of the math leading up to that result will be calculated with an int sized intermediary. Typecasting is needed to explicitly promote the values to a larger type so that the intermediary compuation does not overflow: long_counter = (char_counter[0] | (char_counter[1] << 8)) | ((unsigned long)(char_counter[2] | (char_counter[3] << 8)) << 16); This combines pairs of bytes into two int sized values, then promotes one of them to a long sized value (the other will then also be promoted to the same size automatically) before combining them into a single long. Erik ------------------------------------------------------------------------------ WhatsUp Gold - Download Free Network Management Software The most intuitive, comprehensive, and cost-effective network management toolset available today. Delivers lowest initial acquisition cost and overall TCO of any competing solution. http://p.sf.net/sfu/whatsupgold-sd _______________________________________________ Sdcc-user mailing list Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user