以 long long 数字打印位 (C++)
Printing bits in long long number (C++)
我想打印一个 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.
文字1默认为整数。投到long long解决问题。
std::cout<<(bool)(number&(((long long)1)<<i));
由于 Cpp plus 1 的答案显示您需要将(默认 int)文字 1
修改为 long long 文字 1LL
或 1ll
。
但是,您最好使用 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 -> 0000000000000000000000000000000000000000000000000000000000000001
您获得此输出的原因是因为对于特定的 hardware/compiler 您正在使用:
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'
不同结果的原因是编译器(这里是 clang 6.0)可以在主函数和 printBits
.
中生成不同的代码
在main
中已知number
始终为1,永不改变。也是"obvious",这只能在输出中产生一个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
中,它无法以这种方式进行优化,因为该函数可能会从其他地方调用。所以它在那里执行移位(结果错误)。
我想打印一个 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.
文字1默认为整数。投到long long解决问题。
std::cout<<(bool)(number&(((long long)1)<<i));
由于 Cpp plus 1 的答案显示您需要将(默认 int)文字 1
修改为 long long 文字 1LL
或 1ll
。
但是,您最好使用 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 -> 0000000000000000000000000000000000000000000000000000000000000001
您获得此输出的原因是因为对于特定的 hardware/compiler 您正在使用:
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'
不同结果的原因是编译器(这里是 clang 6.0)可以在主函数和 printBits
.
在main
中已知number
始终为1,永不改变。也是"obvious",这只能在输出中产生一个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
中,它无法以这种方式进行优化,因为该函数可能会从其他地方调用。所以它在那里执行移位(结果错误)。