Почему операция сдвига ниже работает и в конечном итоге равна? Есть ли какое-нибудь название у этого узора? Я пытаюсь выяснить, что творилось в голове у человека, написавшего этот код!
int i = 0x1;
i |= 0x1 << 1;
i |= 0x1 << 2;
i |= 0x1 << 3;
i |= 0x1 << 4;
i |= 0x1 << 5;
int j = 5;
if( ((0x1 << (j + 1)) - 1) == i)
{
// WHY?
}
Я пытался проверить, верно ли это для всех чисел, но работает только до 31.
for (int i = 1; i <= 100; i++) {
int total_1 = 0x1;
for (int j = 1; j <= i; j++) {
total_1 |= 0x1 << j;
}
int total_2 = (0x1 << (i + 1)) - 1;
if (total_2 == total_1) {
} else {
cout << i << endl;
break;
}
}
ОБНОВЛЕНИЕ
Пожалуйста, объясните первую часть, почему они в конечном итоге равны?
2 ответа
Есть ли какое-нибудь название у этого узора?
0x1u << pos
(или просто 1u << pos
) — это шаблон для получения числа, в котором установлен только бит в позиции pos
. Использование подписанного 0x1
обычно является антишаблоном.
i |= 1u << pos
— это шаблон для установки бита в позицию pos
целого числа i
.
(1u << pos) - 1
— это шаблон для создания набора битов только в позициях, меньших, чем pos
.
Почему операция сдвига ниже работает и в конечном итоге равна?
Возможно, это может помочь взглянуть на промежуточные результаты:
// least significant byte
int i = 0x1; // 0b0000'0001
i |= 0x1 << 1; // 0b0000'0011
i |= 0x1 << 2; // 0b0000'0111
i |= 0x1 << 3; // 0b0000'1111
i |= 0x1 << 4; // 0b0001'1111
i |= 0x1 << 5; // 0b0011'1111
int j = 5;
0x1 << (j + 1)
0x1 << 6 // 0b0100'0000
(0x1 << (j + 1)) - 1
0b0100'0000 - 1 // 0b0011'1111
работает только до 31
int
, вероятно, имеет ширину 32 бита в вашей системе. Если вы сдвинете 32-битный 0x1 на 31 или больше, то поведение программы будет неопределенным. Если бы вы использовали 0x1u
, вы могли бы сдвинуться на 31, но 32 и выше были бы UB.
ОБНОВЛЕНИЕ Пожалуйста, объясните первую часть, почему они окажутся равными?
((0x1 << (j + 1)) - 1)
устанавливает j
младших битов в 1
Примере:
Если j
равно 3, j+1
равно 4, 1
со сдвигом на 4 равно 0b1000
; вычтите 1 - вы получите 0b0111
Re: Is there any name for this pattern?
- я посмотрел здесь, этот шаблон используется пару раз, но не называется. Наверное, слишком очевидно :)
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .
int
, что именно вы ожидаете, когда пытаетесь сдвинуть больше битов, чем может быть сдвинуто?c shift operator
в поисковую систему? Что-нибудь еще? По-вашему, что такое бинарный и как он используется для представления целочисленных значений? Если у вас есть целое число, записанное в двоичном формате, например11111
, как вы ожидаете, что будет выглядеть следующее большее целое число? Почему?((0x1 << (j + 1)) - 1) == i
я получил 31 часть - спасибо