I'm having problems creating a 32-bit integer from a 4-byte array. In the following complete, minimal, and verifiable example, converting a byte array containing 0x00, 0x04, 0x04F, 0x45
results in 4F45
(expected result would be 44F45
). I must be overlooking something fundamental here.... can anyone see where I went wrong?
void setup()
{
Serial.begin(9600);
while(!Serial);
}
void loop()
{
uint8_t bytes[4] = {0x00, 0x04, 0x4F, 0x45}; //00044F45
int32_t theInt = byteArrayToInt32(bytes);
Serial.println(theInt, HEX); //Print 4F45
delay(250);
}
uint32_t byteArrayToInt32(uint8_t* bytes)
{
uint32_t i = 0;
i |= bytes[0] << 24;
i |= bytes[1] << 16;
i |= bytes[2] << 8;
i |= bytes[3];
return i;
}
1 Answer 1
The problem is that you are trying to shift uint8_t
more than 8 bits and then OR
it with int32_t
.
You have to cast
the uint8_t
to int32_t
before doing the shift.
void setup()
{
Serial.begin(9600);
while(!Serial);
}
void loop()
{
uint8_t bytes[4] = { 0x00, 0x04, 0x4F, 0x45}; //00044F45
int32_t theInt = byteArrayToInt32(bytes);
Serial.println(theInt, HEX); //Print 4F45
delay(1000);
}
int32_t byteArrayToInt32(uint8_t* bytes)
{
int32_t i = 0;
i |= (int32_t) bytes[0] << 24;
i |= (int32_t) bytes[1] << 16;
i |= (int32_t) bytes[2] << 8;
i |= (int32_t) bytes[3];
return i;
}
-
Note that if the most significant bit of
bytes[0]
is set, then(int32_t) bytes[0] << 24
will shift it into the sign bit, which is undefined behavior. It is safer to cast to auint32_t
, which can in turn be safely assigned to anint32_t
.Edgar Bonet– Edgar Bonet2019年06月10日 09:14:34 +00:00Commented Jun 10, 2019 at 9:14 -
Hmm, so doing as you suggested fixes the problem, however I'm very perplexed as to why the left shift by 8 bits worked originally, then?You'reAGitForNotUsingGit– You'reAGitForNotUsingGit2019年06月10日 14:26:11 +00:00Commented Jun 10, 2019 at 14:26
-
it appears that the left shift function uses a 16 bit buffer .... possibly because it uses the same code for 16 bit shiftsjsotola– jsotola2019年06月10日 18:53:52 +00:00Commented Jun 10, 2019 at 18:53
uint32_t
, no difference :(