Storing a Long number in a Byte array

Just a quick question. If I declare an array as a byte say

long test = 123456789;
byte array[4]

and put a long number in the array at address 0

array[0] = test;

is it safe to assume the long will be stored in the array as 4 bytes? It compiles fine, I just don't have my Arduino handy to test it.

No, it is not at all safe to assume that. With full error messages enabled, you'd probably get an implicit narrowing cast error.

Darn it! Thanks.

Could a union work to map a long on top of a 4 byte array?

Lefty

yes

Thanks guys! Not familiar with the use of unions so I guess I've got some reading to do.

Oops, that's a "implicit narrowing cast warning", not an error.

Bah! Safety schmafety. :)

You can do this, which will generally work just like you want.

long big = 123456789;
byte* littles = (byte*)&bigs;

You just have to be aware that atmega's are little-endian, so that statement is functionally equivalent to this:

byte littles[4] = { 0x15, 0xcd, 0x5b, 0x7 };

When I actually do this, I'm working in hex and explicitly-sized types, e.g.

uint32_t big = 0x12345678;
uint8_t* littles = (uint8_t*)&big;  // same as littles[4] = { 0x78, 0x56, 0x34, 0x12 };
same as littles[4] = { 0x78, 0x56, 0x34, 0x12 };

But that isn't the same as what the OP implied - the data hasn't moved, you've simply provided a pointer to it, not assigned it to a new variable.

So let's try a reverse approach. Here's what I'm trying to do. I need an array of bytes that is about 28 bytes in size that will contain any combination of longs, ints and bytes as data. I want to be able to shift the data out to the master one byte at a time and have the master reassemble each byte into it's corresponding data type. Basically I'm making a I2C slave device so I want to just move the pointer down the array to shift the data out.

wayneft:
J…
is it safe to assume the long will be stored in the array as 4 bytes? It compiles fine, I just don’t have my Arduino handy to test it.

No. But the compiler knows. It has to, right?

Try this:

void setup()
{
    Serial.begin(9600);
}

unsigned long testLong = 0x76543210;

// A pointer to byte.  The value is the address of
// testLong.  C++ requires a cast to assign
// a pointer value to a pointer of a different
// data type.
byte * bPoint = (byte *)&testLong;

void loop()
{
    Serial.print("Here is the unsigned long variable           : ");
    Serial.println(testLong, HEX);
    
    Serial.print("Here are its bytes in order stored in memory :");
    for (int i = 0; i < sizeof(testLong); i++) {
        Serial.print(" 0x");Serial.print(bPoint[i],HEX);
    }
    Serial.println();
    
    delay(10000);
}

Output:


Here is the unsigned long variable           : 76543210
Here are its bytes in order stored in memory : 0x10 0x32 0x54 0x76

Try it again with int, float, etc, array of chars, array of ints, array of floats. some kind of struct, etc…

Try it again with one or both variables declared and assigned inside the loop() function. Etc…

Regards,

Dave

I need an array of bytes that is about 28 bytes in size that will contain any combination of longs, ints and bytes as data

So, the byte pointer is the way to go, but that isn't what you implied in your first post.

Thanks again guys.

wayneft: So let's try a reverse approach. Here's what I'm trying to do. I need an array of bytes that is about 28 bytes in size [u]that will contain any combination of longs, ints and bytes as data.[/u] I want to be able to shift the data out to the master one byte at a time and have the master reassemble each byte into it's corresponding data type. Basically I'm making a I2C slave device so I want to just move the pointer down the array to shift the data out.

ANY combination of datatypes, or a specific combination of datatypes? If the combination is not predetermined, how will the master separate and reassemble the data it receives?

The order will be determined by the user via a control register.