That is an easy to make mistake.
The number 1 defaults to a integer type 'int', which is a 16-bit signed integer for the basic Arduino boards. You should shift a 32-bit value and not just a integer'int'.
This is my solution, I shift a 'UL' (unsigned long) number:
void setup()
{
Serial.begin(115200);
for (int i = 0; i < 16; i++)
{
uint32_t x = 1UL << i;
Serial.print("x is : ");
Serial.println(x, BIN);
}
}
void loop() {}
In Wokwi:
[EDIT] Changed occording to @anon73444976 in Reply 6
By default, calculations are done with 16-bit integers (on an 8-bit microcontroller). At the moment that you shift the integer 1 15 times, the results is 1000 0000 which is a negative number.
You need to force the compiler to use an unsigned 32 bit number by using 1UL. Below a slightly modified version of your code
void setup() {
Serial.begin(115200);
}
void loop() {
for (int i = 0; i < 16; i++)
{
Serial.println(i);
uint32_t x = 0;
x = (uint32_t)(1UL << (uint32_t)i);
Serial.print("x is : ");
Serial.println(x, BIN);
}
delay(500);
}
Note:
Your original casts are not needed, x = 1UL << i; works as well.
This is one case where the "the usual conversions" are not done. If you were using +, -, * or many other dyadic operators, the fact that one operand was 'uint32_t' would convert the other side from 'int' to 'uint32_t'. But not shifting.