Одна проблема с 1 << x
становится очевидной, когда вы сдвигаете 1 достаточно далеко влево.На машинах с двойным представлением для целых чисел это значение внезапно становится отрицательным.Предполагая, что int
ширина 32 бита:
#include <stdio.h>
int
main(int argc, const char** argv)
{
printf("%d\n", (1 << 30));
printf("%d\n", (1 << 31));
printf("%ud\n", (1U << 30));
printf("%ud\n", (1U << 31));
return 0;
}
дает
1073741824
-2147483648
1073741824d
2147483648d
на моей машине.Это может быть неожиданным в других частях кода.В частности, поскольку обратный сдвиг не обязательно эквивалентен из-за расширения со знаком:
#include <stdio.h>
int
main(int argc, const char** argv)
{
printf("%d\n", (2 << 29) >> 29);
printf("%d\n", (2 << 30) >> 30);
printf("%u\n", (2U << 29) >> 29);
printf("%u\n", (2U << 30) >> 30);
return 0;
}
приводит к
2
-2
2
2
Обратите внимание, что он перевернул знак на второй выходной строке ...