Почему std :: bitset предлагает больше доступных бит, чем sizeof говорит, что есть?
Я работаю над некоторыми проблемами с небольшими манипуляциями в C++ и сталкивался с этим, пытаясь визуализировать мои шаги. Я понимаю, что количество бит, присвоенных различным примитивным типам, может варьироваться от системы к системе. Для моей машины sizeof(int)
выводит 4
, поэтому у меня есть 4 char
бит для моей стоимости. Я также знаю теперь, что определение байта обычно составляет 8 бит, но это не обязательно так. Когда я CHAR_BIT
я получаю 8
. Поэтому я ожидаю, что для моих значений int
будет в общей сложности 32 бита.
Затем я могу продолжить и напечатать двоичное значение моего int
на экране:
int max=~0; //All my bits are turned on now
std::cout<<std::bitset<sizeof(int)*CHAR_BIT>(max)<<std::endl;
$:11111111111111111111111111111111
Я могу увеличить размер бита, если хочу:
int max=~0;
std::cout<<std::bitset<sizeof(int)*CHAR_BIT*3>(max)<<std::endl;
$:000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111
Почему их так много? Я ожидал, что у меня будет всего 32, с нулями. Вместо этого в два раза больше, что происходит?
Когда я повторяю эксперимент с unsigned int
, который имеет тот же размер, что и int
, лишние не появляются:
unsigned int unmax=~0;
std::cout<<std::bitset<sizeof(unsigned int)*CHAR_BIT*3>(unmax)<<std::endl;
$:000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111
Ответы
Ответ 1
Конструктор std::bitset
принимает unsigned long long
, и когда вы пытаетесь назначить -1 (что равно ~0
в int
) для unsigned long long
, вы получаете 8 байт (64 бит) стоимости 1s.
Это не происходит с unsigned int
потому что вы назначаете значение 4294967295 вместо -1, которое равно 32 1 с unsigned long long
Ответ 2
Когда вы пишете int max=~0;
, max
будет 32 бита, заполненного 1s, который интерпретируется как integer -1
.
Когда вы пишете
std::bitset<sizeof(int)*CHAR_BIT>(max)
// basically, same as
std::bitset<32>(-1)
Вы должны иметь в виду, что конструктор std::bitset
принимает unsigned long long
. Таким образом, -1
который вы передаете ему, преобразуется в 64-битное представление -1
, которое содержит 64 бита, заполненных 1 (поскольку у вас есть отрицательное значение, расширение знака поддерживает его как таковое, заполняя 32 левые бит с 1 сек.).
Поэтому конструктор std::bitset
получает unsigned long long
заполненный 1s, и инициализирует 32 бита, которые вы задали с помощью 1s. Итак, когда вы печатаете его, вы получаете:
11111111111111111111111111111111
Затем, когда вы пишете:
std::bitset<sizeof(int)*CHAR_BIT*3>(max)
// basically, same as
std::bitset<96>(-1)
Конструктор std::bitset
инициализирует 64 самых правых бита 96, которые вы задали, с unsigned long long
которую вы передали, поэтому эти 64 бита заполнены 1s. Остальные биты (32 слева) инициализируются нулями. Поэтому, когда вы печатаете его, вы получаете:
000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111
С другой стороны, когда вы пишете unsigned int unmax=~0;
, вы назначаете все 1s unsigned int
, так что вы получаете UINT_MAX
.
Затем, когда вы пишете:
std::bitset<sizeof(unsigned int)*CHAR_BIT*3>(unmax)
// basically, same as
std::bitset<96>(UINT_MAX)
UINT_MAX
который вы передаете, преобразуется в 64-битное представление, которое представляет собой 32 самых правых бита, заполненных 1 и оставшихся всех 0 (поскольку у вас есть положительное значение, расширение знака поддерживает его как таковое, заполняя 32 крайних левых бита 0).
Таким образом, unsinged long long
который получает конструктор std::bitset
, представлен как 32 0s, за которым следуют 32 1s. Он будет инициализировать 64 самых правых бита из 96, которые вы задали с 32 0, за которыми следуют 32 1. Остальные 32 левых бита (из 96) инициализируются нулями. Поэтому, когда вы печатаете его, вы получаете (64 0 с 32-ю):
000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111