Что вы пропустили, так это то, что операции по сдвигу битов в строках являются модом 32. Поскольку 0x1111
- это int
, операция - 0x1111 << (32 % 32)
, то есть 0x1111 << 0
, то есть просто 0x1111
.
Что вы, вероятно, хотите, это 0x1111L << 32
.
Из раздела 7.9 спецификации C #:
Когда тип x равен int
или uint
, счет сдвига задается младшими пятью битами count
. Другими словами, число сдвигов вычисляется из count & 0x1F
.
Когда тип x равен long
или ulong
, счет сдвига задается младшими шестью битами count
. Другими словами, число сдвигов вычисляется из count & 0x3F
.
На некоторых аппаратных архитектурах смещение int на 32 даст 0, в то время как на других архитектурах будет то же самое int. Чтобы иметь согласованное поведение, разработчики C # должны были выбрать один из этих вариантов. Текущее поведение просто требует выполнения & 0x1F
для счетчика сдвигов на архитектурах, которые в противном случае дают 0. Однако всегда возвращение 0 потребует сравнения и ветвления на архитектурах, которые дают int. Поскольку филиалы, как правило, дороги, имеет смысл выбрать наиболее быстрый вариант в большинстве случаев.