Я пытался преобразовать целое число в его эквивалентное двоичное представление.
Я использовал следующий алгоритм
void decimal_to_binary(uint32_t number)
{
char bitset[32];
for(uint32_t i=0; i<32; ++i)
{
if((number & (1 << i)) != 0)
{
bitset[31-i] = '1';
}
else
{
bitset[31-i] = '0';
}
}
for(uint32_t i=0; i<32; ++i)
{
cout << bitset[i];
}
cout << "\n";
}
Когда я запускаю эту функцию для, скажем, ‘5’, объявленного как uint32_t, я получаю правильные результаты
decimal_to_binary(5)
00000000000000000000000000000101
Но когда я объявляю число как uint64_t, а также изменяю размер набора битов на 64 бита, результаты совершенно разные
Добавление кода, чтобы сделать то же самое
void decimal_to_binary(uint64_t number)
{
char bitset[64];
for(uint64_t i=0; i<64; ++i)
{
if((number & (1 << i)) != 0)
{
bitset[63-i] = '1';
}
else
{
bitset[63-i] = '0';
}
}
for(uint64_t i=0; i<64; ++i)
{
cout << bitset[i];
}
cout << "\n";
}
decimal_to_binary(5)
0000000000000000000000000000010100000000000000000000000000000101
Я вижу те же результаты, что и в uint32, но помещаю один рядом с другим.
Это заставило меня задуматься о том, как реализован uint64_t в языке программирования, таком как CPP ??
Я попытался получить более подробную информацию, посмотрев на stdint заголовочный файл, но ссылка там мне очень помогла.
Спасибо заранее за ваше время!!
(1 << i) в вашем 64-битном коде может использоваться обычный 32-битный int для 1. (размер слова по умолчанию)
Таким образом, 1 смещается полностью.
Я не понимаю, как это производит вывод, который вы предоставили, хотя 🙂
Используйте 1ull для константы (unsigned long long)
Проблема заключается в этой строке:
if((number & (1 << i)) != 0)
<<
Тип возврата оператора — это тип левого операнда, который, по-видимому, в вашей реализации предполагается длиной 32 бита. Сдвиг типа дальше, чем общее количество его битов, приводит к неопределенному поведению.
Чтобы исправить это используйте
if((number & (static_cast<uint64_t>(1) << i)) != 0)
перевод 1
более 32 бит — это неопределенное поведение, если это только 32-битное число. Неопределенное поведение означает, что оно может делать что угодно. Как сказал Рэймонд Чен, правый операнд, вероятно, ограничивается 31 (поразрядным — с 32). Вот почему вы получаете две копии нижней половины 64-битного значения. Попробуй сдвинуть number
направо вместо 1
налево:
void decimal_to_binary(uint64_t number)
{
char bitset[64];
for(size_t i=0; i<64; ++i)
{
if(number & 1) != 0)
{
bitset[63-i] = '1';
}
else
{
bitset[63-i] = '0';
}
number >>= 1;
}
for(size_t i=0; i<64; ++i)
{
cout << bitset[i];
}
cout << "\n";
}