8

我想打印 long long 数字的所有位。当我在 main() 中执行此操作时,一切都很好,但是在 printBits() 函数(代码相同)中,第 32 位有一个额外的 1。

编码:

#include <iostream>

void printBits(long long number)
{
    std::cout<<number<<" -> ";
    for (char i=63; i>=0; --i)
    {
        std::cout<<(bool)(number&(1<<i));
    }
    std::cout<<std::endl;
}

int main()
{
    long long number=1;

    std::cout<<number<<" -> ";
    for (char i=63; i>=0; --i)
    {
        std::cout<<(bool)(number&(1<<i));
    }
    std::cout<<std::endl;

    printBits(number);

    return 0;
}

结果是:

1 -> 0000000000000000000000000000000000000000000000000000000000000001
1 -> 0000000000000000000000000000000100000000000000000000000000000001

Process returned 0 (0x0)   execution time : 0.012 s
Press any key to continue.
4

3 回答 3

4

文字 1 默认为整数。将其转换为 long long 以解决问题。

std::cout<<(bool)(number&(((long long)1)<<i));
于 2018-05-01T20:15:54.040 回答
3

结果不同的原因是编译器(这里是 clang 6.0)可以在 main 函数和printBits.

main众所周知,number它始终为 1,并且永远不会改变。同样“显而易见”的是,这只能1在输出中产生一个。所以优化器将循环重写为:

for (char i=64; i > 0; --i)
{
    std::cout<< (i == 1 ? 1 : 0);
}

看马,没有轮班!

组件看起来像这样

012B13CC  mov         bl,40h    ; i = 40h = 64  
012B13CE  xchg        ax,ax     ; nop to align the loop
main+30h: 
012B13D0  xor         eax,eax  
012B13D2  cmp         bl,1      ; i == 1?
012B13D5  mov         ecx,esi  
012B13D7  sete        al  
012B13DA  push        eax  
012B13DB  call        edi       ; edi -> operator<<
012B13DD  dec         bl  
012B13DF  jg          main+30h (012B13D0h)  

它不能以printBits这种方式优化,因为该函数可能会从其他地方调用。所以它在那里执行转变(结果错误)。

于 2018-05-01T21:56:45.017 回答
3

正如 Cpp plus 1 的答案所示,您需要将(默认 int)文字修改 1为 long long 文字1LL1ll.

但是,您最好使用std::bitset而不是您的函数:

#include <bitset>
long long number = 1;  // int number = 1;  also works
std::bitset<64> bits(number);
std::cout << number << " -> " << bits << std::endl;

产量:

1 -> 000000000000000000000000000000000000000000000000000000000000000001

您获得此输出的原因是因为您使用的特定硬件/编译器:

a << x 操作按以下方式工作:a << (x mod (8 * sizeof(a))。因此为1你得到 1 << (x mod 32). 这意味着在第 32 次循环迭代中:

std::cout << (bool)(number & (1 << 32));
// becomes
std::cout << (bool)(number & (1 << 0));
// printing '1'
于 2018-05-01T20:21:54.100 回答