# Unexpected results with bit shift

I am trying this on an Arduino Mega.
I get some unexpected results shifting a bit in a 32bit value;

My initial goal was to 'emulate' an array of 24 booleans. I was hoping to store them in one unsigned Long. It all worked well but got some unexpected results, that is why I wrote this little script to test the error...

``````  Serial.begin(112500);

//unsigned long LongVar1;
uint32_t LongVar1;
for (byte s=0 ; s<24 ; s++)
{
Serial.print(" 1 << ");
Serial.print(s);
Serial.print(" => ");
LongVar1 = 1 << s;
Serial.println(LongVar1,BIN);

}
``````

Result in Serial Monitor :

1 << 0 => 1
1 << 1 => 10
1 << 2 => 100
1 << 3 => 1000
1 << 4 => 10000
1 << 5 => 100000
1 << 6 => 1000000
1 << 7 => 10000000
1 << 8 => 100000000
1 << 9 => 1000000000
1 << 10 => 10000000000
1 << 11 => 100000000000
1 << 12 => 1000000000000
1 << 13 => 10000000000000
1 << 14 => 100000000000000
1 << 15 => 11111111111111111000000000000000
1 << 16 => 0
1 << 17 => 0
1 << 18 => 0
1 << 19 => 0
1 << 20 => 0
1 << 21 => 0
1 << 22 => 0
1 << 23 => 0

What is unexpected?
An int is sixteen bits wide on an eight bit Arduino

``````LongVar1 = 1 << s;
``````

That line shifts a 1 of type "int" left by "s" bits. "int" is only 16 bits wide on many of the Arduinos. Change "1" to "1UL" to make it an unsigned long to match "LongVar1".

Hi, Awol thanks for the quick reply...

With an unsigned Int it works fine up until 15 (which is expected) .

With an unsigned Long it works only up until 14??? Which is actually less?
I thought Longs were 32 bit?

christop:

``````LongVar1 = 1 << s;
``````

That line shifts a 1 of type "int" left by "s" bits. "int" is only 16 bits wide on many of the Arduinos. Change "1" to "1UL" to make it an unsigned long to match "LongVar1".

THANKS!!! You're a life saver..

So the working code should be :

``````Serial.begin(112500);

//unsigned long LongVar1;
uint32_t LongVar1;
for (byte s=0 ; s<24 ; s++)
{
Serial.print(" 1 << ");
Serial.print(s);
Serial.print(" => ");
LongVar1 = 1UL << s;
Serial.println(LongVar1,BIN);

}
``````

Just one more question, say I want to shift an entire byte 24 to the left... How would I do that?

``````byte b1=B10101010;

unsigned long Longy= b1 << 24 ;  // Again does not work...
``````

Cast the byte to an appropriate width

I am afraid I don't know how to do that :-[

Kevin77:
I am afraid I don't know how to do that :-[

``````byte myByte = 0b01010101;
uint32_t myUL = (uint32_t)myByte << 24;
``````