Splitting Long into Bytes & recombining

I’m trying to write a Long to the EEPROM, so I’m splitting it into 4 bytes and writing those, then read and recombine later. I’m having trouble getting the code to simply do the split and recombine properly - the EEPROM part otherwise is working fine, as is the splitting. I’m running into problems recombining the bytes into a Long. I am aware of the EEPROM write anything code, but would like to figure out why this isn’t working. Here’s my code:

unsigned long groundpress=101325;
unsigned char byte1, byte2, byte3, byte4;
unsigned long recomb;

void setup(){
  Serial.begin(9600);
  while(!Serial)
  Serial.print(groundpress, DEC);
  Serial.print("\t");
  Serial.print(groundpress, HEX);
  Serial.print("\t");
  Serial.println(groundpress, BIN);
  
  byte4 = lowByte(groundpress);
  groundpress= groundpress >> 8;
  byte3 = lowByte(groundpress);
  groundpress= groundpress >> 8;
  byte2 = lowByte(groundpress);
  groundpress= groundpress >> 8;
  byte1 = groundpress;
  
  Serial.print("Byte1: ");
  Serial.print(byte1, HEX);
  Serial.print("\t");
  Serial.println(byte1, BIN);
  Serial.print("Byte2: ");
  Serial.print(byte2, HEX);
  Serial.print("\t");
  Serial.println(byte2, BIN);
  Serial.print("Byte3: ");
  Serial.print(byte3, HEX);
  Serial.print("\t");
  Serial.println(byte3, BIN);
  Serial.print("Byte4: ");
  Serial.print(byte4, HEX);
  Serial.print("\t");
  Serial.println(byte4, BIN);
  
  recomb = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
  
  Serial.print("Recombined: ");
  Serial.print(recomb, DEC);
  Serial.print("\t");
  Serial.print(recomb, HEX);
  Serial.print("\t");
  Serial.println(recomb, BIN);
}

void loop()
{}

And here’s the result:

101325 18BCD 11000101111001101
Byte1: 0 0
Byte2: 1 1
Byte3: 8B 10001011
Byte4: CD 11001101
Recombined: 4294937549 FFFF8BCD 11111111111111111000101111001101

but would like to figure out why this isn't working.

Google "sign extension"

Looking at this page: << - Arduino Reference I don't understand how that would cause my problem. All my data types are unsigned, and the problem occurs when I'm left shifting, not right shifting.

  recomb = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;

Try casting byte1, byte2, etc. to unsigned long.

You are victim of casting to the default type, namely int (signed).
In this line the sub-expressions like “byte1 << 24” are cast to the default int type,
which is signed 16 bit.

  recomb = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;

How about using something like this:

  recomb = byte1 ;
  recomb = (recomb << 8) | byte2 ;
  recomb = (recomb << 8) | byte3 ; 
  recomb = (recomb << 8) | byte4 ;

in which all the intermediate expressions are unsigned. (Caveat, I haven’t tested this)

Awesome, both of those suggestions worked. Appreciate it! MarkT, that makes (some) sense now why it was causing a problem. Cheers

uint32_t endian_swap(uint32_t& value)
{
    uint8_t*    pLHS = (uint8_t*)(&value) - 1;
    uint8_t*    pRHS = (uint8_t*)(&value) + sizeof(uint32_t);
    uint8_t     t;
    while ( ++pLHS < --pRHS )
    {
        t       = *pLHS;
        *pLHS   = *pRHS;
        *pRHS   = t;
    }

    return value;
}


void loop()
{}


void setup()
{
    const uint32_t n	= 101325;    // 0x18BCD
    uint32_t       v	= n;
    v	                = endian_swap(v);

    for ( size_t i = 0; i < sizeof(v); i++ )
    {
       Serial.print(((uint8_t*)&v)[i], HEX);
    }

    // should've output CD8B01
    Serial.print("\n");
}