speedy-MACHO speedy-MACHO - 24 days ago 6
C++ Question

Convert 4 bytes to long on Arduino error

I'm having a really strange inconsistancy.

I'm preparing for reading from binary files on Arduino (for a midi player, in case you were interested).
If I try to combine 4 bytes on Arduino to a long, it gives me a wrong result.

However, if I use the equivalent code on PC, I get the correct value.

Input is: 0x12481248 (0x12, 0x48, 0x12, 0x48) (really a random number).

Arduino gives: 4680.

Code::Blocks gives: 306713160.

4680 is the same as 0x1248, and the result you get when you use an int instead of long on Arduino (2 bytes omitted).

Arduino code:

void setup(){
Serial.begin(57600);
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
unsigned long testint2 = 306713160;
Serial.println(testint);
Serial.println(testint2);
}

void loop(){}


testint2 is to show that it isn't caused by Serial.println(). Serial Monitor output is indeed:

4680

306713160

C++ code:

#include <iostream>

using namespace std;

int main(){
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
cout << testint;
}


Any idea what's going on?

Also, does anyone know a better/prettier way of converting bytes with Arduino/SD library?

nnn nnn
Answer

On Arduino, int size is 16 bits.

In this line:

unsigned long testint = read1<<24|read2<<16|read3<<8|read4;

even if the result is stored in a unsigned long (32 bits), the bitwise operations are done on ints.

Change this line to:

unsigned long testint = (unsigned long)read1 << 24 
                      | (unsigned long)read2 << 16
                      | (unsigned long)read3 << 8
                      | (unsigned long)read4;