 # Long to Char Array and Back

I want to store a long into a character array for writing to an SD card…and then, obviously, get it back to a long! I found the below code but the long that I get back is 722 not what I put in. Since bitwise operations make my head hurt I need help badly!

``````    unsigned long int longInt = 1234567890;
unsigned char byteArray;

// convert from an unsigned long int to a 4-byte array
byteArray = (int)((longInt >> 24) & 0xFF) ;
byteArray = (int)((longInt >> 16) & 0xFF) ;
byteArray = (int)((longInt >> 8) & 0XFF);
byteArray = (int)((longInt & 0XFF));

unsigned long int anotherLongInt;

anotherLongInt = ( (byteArray << 24)
+ (byteArray << 16)
+ (byteArray << 8)
+ (byteArray ) );
``````
``````anotherLongInt = ( ((unsigned long)byteArray << 24)
+ ((unsigned long)byteArray << 16)
+ ((unsigned long)byteArray << 8)
+ ((unsigned long)byteArray ) )
``````

shouldn’t this work too?

``````for(int i =0; i < sizeof(byteArray); i++)
{
anotherLongInt |= ( (long)byteArray[i]) << (i*8) );
}
``````

You can also do:

``````unsigned long x=0x12345678;
byte* bytes;

bytes=(byte*)(&x); // bytes={0x78,0x56,0x34,0x12};

x=*((unsigned long*) bytes);
``````

shouldn't this work too?

No, I don't believe so.

Thanks for the very quick responses. Am happily on to find my next problem. :)

A much easier way (as long as there are no inter-machine endian issues) is to use a union.

AWOL: Thanks for your first answer...it is what I just stuck in my code. Is there any chance I could ask for a code example of using a union? My education in bit level operations was a VERY very VERY long time ago...

The great thing about a union is that it isn't bit-level at all - just write your variable to one part of the union, and read it back from another. Useful tutorial

(BTW, I'm not entirely sure the solution I gave earlier is correct - bitwise OR would be better than addition, but I've a sneaking suspicion there's still a sign-extension issue lurking)

Here is a handy function for castinig types in c++

``````// safely cast between types without breaking strict aliasing rules
template<typename ReturnType, typename OriginalType>
ReturnType alias_cast( OriginalType Variable )
{
union{
OriginalType  In;
ReturnType    Out;
};
In = Variable;
return Out;
}
``````

Then you can use like:

``````unsigned long lngData = *alias_cast< unsigned long* >( bytearray );
bytearray = alias_cast< byte* >( u_Data );
``````

Or even:

``````struct long_t{
unsigned char first;
unsigned char second;
unsigned char third;
unsigned char fourth;
};

unsigned lngData = 0x11223344;

Serial.print( alias_cast< long_t >( lngData ).third );
``````

AWOL:

Wisar

...sometimes

``````void memrev(uint8_t array[], size_t cb)
{
uint8_t*    pLHS = array - 1;
uint8_t*    pRHS = array + cb;
uint8_t     t;
while ( ++pLHS < --pRHS )
{
t       = *pLHS;
*pLHS   = *pRHS;
*pRHS   = t;
}
}

// ... code fragment ...

const unsigned long n   = 1234567890UL; // 0x499602D2

unsigned long       v   = n;
unsigned char*      p   = (unsigned char*)&v;
memrev(p, sizeof(v));

Serial.println(p, HEX);
Serial.println(p, HEX);
Serial.println(p, HEX);
Serial.println(p, HEX);
``````