Преобразование целого числа в двоичное показывает различные выходные данные, когда число объявлено как uint32 и uint64

Я пытался преобразовать целое число в его эквивалентное двоичное представление.

Я использовал следующий алгоритм

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

Решение

(1 << i) в вашем 64-битном коде может использоваться обычный 32-битный int для 1. (размер слова по умолчанию)

Таким образом, 1 смещается полностью.
Я не понимаю, как это производит вывод, который вы предоставили, хотя 🙂

Используйте 1ull для константы (unsigned long long)

3

Другие решения

Проблема заключается в этой строке:

if((number & (1 << i)) != 0)

<< Тип возврата оператора — это тип левого операнда, который, по-видимому, в вашей реализации предполагается длиной 32 бита. Сдвиг типа дальше, чем общее количество его битов, приводит к неопределенному поведению.

Чтобы исправить это используйте

if((number & (static_cast<uint64_t>(1) << i)) != 0)
2

перевод 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";
}
2
По вопросам рекламы [email protected]