-1

我试图将整数转换为其等效的二进制表示。

我正在使用以下算法

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 并将 bitset 的大小更改为 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头文件来获取更多详细信息,但那里的链接确实帮助了我很多。

在此先感谢您的时间!!

4

3 回答 3

3

64 位代码中的 (1 << i) 可能使用常规的 32 位 int 作为 1。(默认字长)

所以 1 完全移出。我不明白这如何产生您提供的输出:)

使用 1ull 作为常量(unsigned long long)

于 2014-04-15T14:36:33.757 回答
2

如果它只是一个 32 位数字,则移动1超过 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";
}
于 2014-04-15T14:43:54.593 回答
2

问题出在这一行:

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

运算符的<<返回类型是左操作数的类型,显然在您的实现中假定为 32 位长。将类型移动到比其总位数更远的位置会产生未定义的行为。

要修复它,请使用

if((number & (static_cast<uint64_t>(1) << i)) != 0) 
于 2014-04-15T14:41:59.873 回答