我试图将一个整数转换为其等效的二进制表示。
我使用了以下算法
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";
}
当我对例如声明为uint32_t的'5'运行此函数时,我得到了正确的结果
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头文件来获得更多细节,但那里的链接确实帮了我很多忙。
提前感谢您抽出时间!!
64位代码中的(1<<i)可能对1使用常规的32位int。(默认单词大小)
因此,1被完全移出。我不明白这是如何产生你提供的输出的:)
使用1ull作为常量(无符号长-长)
问题在于这一行:
if((number & (1 << i)) != 0)
<<
运算符的返回类型是左操作数的类型,在您的实现中,它显然被假定为32位长。将一个类型移位超过其位的总数会产生未定义的行为。
要修复它,请使用
if((number & (static_cast<uint64_t>(1) << i)) != 0)
如果1
只是一个32位数字,则将其移位超过32位是未定义的行为。未定义的行为意味着它可以做任何事情。正如Raymond Chen所说,它可能会将右侧操作数限制为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";
}