Этот вопрос вдохновлен другими вопросами от StackOverflow. Сегодня, просматривая StackOverflow, я столкнулся с проблемой сдвига битов переменной на значение k, которое> = ширина этой переменной в битах. Это означает смещение 32-битного целого на 32 или более битовых позиций.
Сдвиг влево целого числа на 32 бита
Неожиданный результат C / C ++ операторов побитового сдвига
Из этих вопросов очевидно, что если мы попытаемся сдвинуть число на k битов, которые> = битовая ширина переменной, будут взяты только младшие значащие биты log2k. Для 32-разрядного типа int младшие 5 битов маскируются и принимаются за величину сдвига.
В общем, если w = ширина переменной в битах,
x >> k
становится x >> (k % w)
Для int
это x >> (k % 32)
.
Счет маскируется до пяти битов, что ограничивает диапазон счетчика от 0 до 31.
Итак, я написал небольшую небольшую программу для наблюдения за поведением, которое теоретически должно быть произведено. Я написал в комментариях итоговую величину сдвига% 32.
#include <stdio.h>
#include <stdlib.h>
#define PRINT_INT_HEX(x) printf("%s\t%#.8x\n", #x, x);
int main(void)
{
printf("==============================\n");
printf("Testing x << k, x >> k, where k >= w\n");
int lval = 0xFEDCBA98 << 32;
//int lval = 0xFEDCBA98 << 0;
int aval = 0xFEDCBA89 >> 36;
//int aval = 0xFEDCBA89 >> 4;
unsigned uval = 0xFEDCBA89 >> 40;
//unsigned uval = 0xFEDCBA89 >> 8;
PRINT_INT_HEX(lval)
PRINT_INT_HEX(aval)
PRINT_INT_HEX(uval)
putchar('\n');
return EXIT_SUCCESS;
}
И вывод не соответствует ожидаемому поведению команд смены!
==============================
Testing x << k, x >> k, where k >= w
lval 00000000
aval 00000000
uval 00000000
=============================================== ======================
На самом деле я был немного запутан с Java. В C / C ++ смещение int на число битов, превышающее ширину бит, может быть уменьшено на k% w, но это не гарантируется стандартом C. Нет правила, согласно которому такое поведение должно происходить постоянно. Это неопределенное поведение.
Однако в Java это так. Это правило языка программирования Java.
Описание операторов Bitshift в спецификации языка Java
Странный результат смещения целочисленного значения Java влево
java: расстояние сдвига для int ограничено 31 битом