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

Converting unsigned char[] to long?

How can you access the individual bytes making up a variable of type long? What I need to do is move a 24-bit (3 bytes) unsigned char array into a long variable. An example:

unsigned char a[3];
unsigned long b;

a[0] = 0x02;
a[1] = 0xFF;
a[2] = 0xFF;

?????
?????


TIA!
James

Parents
  • You could use a union, cast a pointer, or do it with shifts.

    Shifting is portable but may be slow;
    The others are non-portable, but likely to be fast.

    You will also need to read the section in the Manual about C51's internal data representation - byte ordering, etc

    You should also do a 'Search, as it's been discussed many times before!
    (hence just a brief answer here)

Reply
  • You could use a union, cast a pointer, or do it with shifts.

    Shifting is portable but may be slow;
    The others are non-portable, but likely to be fast.

    You will also need to read the section in the Manual about C51's internal data representation - byte ordering, etc

    You should also do a 'Search, as it's been discussed many times before!
    (hence just a brief answer here)

Children
  • Maybe you could declare a

    enum
    a long type member and a unsigned char array ,they share the same space but you can access it with differet type.

  • I run into this problem in a few places in my code. A union/array is much faster with Keil C51 than shifting. The code generated takes the shift very literally, and ripples one bit through the carry all the way through your U32, n times. (I've wished for strength reduction on multiples of 8 in the shifts.) Those shifts by 24 to get to the high byte are death to speed, and the library calls to the U32 shift function takes up space, too. The union/array approach usually generates a nice direct access to the proper byte or register.

    typedef union
        {
        U16 u16;
        U8  array[2];
    #if defined(CPU_ENDIAN_BIG)
        struct { U8 msb; U8 lsb; } bytes;
    #elif defined(CPU_ENDIAN_LITTLE)
        struct { U8 lsb; U8 msb; } bytes;
    #else
    #error Must define CPU_ENDIAN_BIG or _LITTLE
    #endif
        } MultiByte16;
    

  • "Maybe you could declare a enum"

    Surely you mean union, not enum??!!

  • Thanks for all the ideas. Since I had a lot of already declared and used variables, a union was pretty much out of the question.

    Casting the pointer seemed to do the trick just fine.

    Thanks!
    James

  • "Casting the pointer seemed to do the trick just fine."

    but don't forget that it relies upon C51's internal data representation - so it would be a good idea to do something like Drew's idea to ensure that nobody forgets this and tries to re-use the code on a different target...