我编写了以下程序来输出一个整数的二进制等价物(我检查了我的系统上的int是4个字节)它是4个字节.但输出并不合适.代码是:
#include<iostream>
#include<iomanip>
using namespace std;
void printBinary(int k){
for(int i = 0; i <= 31; i++){
if(k & ((1 << 31) >> i))
cout << "1";
else
cout << "0";
}
}
int main(){
printBinary(12);
}
Run Code Online (Sandbox Code Playgroud)
我哪里弄错了?
Yu *_*Hao 29
问题在于1<<31.因为2 31不能用32位有符号整数表示(范围-2 31到2 31 - 1),所以结果是未定义的[1].
修复很简单:1U<<31.
[1]:自C++ 14以来,行为是实现定义的.
这个表达式不正确:
if(k & ((1<<31)>>i))
Run Code Online (Sandbox Code Playgroud)
int是一种带符号的类型,因此当您移动131次时,它将成为系统上的符号位.之后,将结果右移i一次符号 - 扩展数字,这意味着顶部位保持为1s.最终得到一个如下所示的序列:
80000000 // 10000...00
C0000000 // 11000...00
E0000000 // 11100...00
F0000000 // 11110...00
F8000000
FC000000
...
FFFFFFF8
FFFFFFFC
FFFFFFFE // 11111..10
FFFFFFFF // 11111..11
Run Code Online (Sandbox Code Playgroud)
要解决此问题,请将表达式替换为1 & (k>>(31-i)).这样,您可以避免因移位到符号位置而导致的未定义行为*1.
* C++ 14更改了定义,因此1在32位中向左移动31次int不再是未定义的(谢谢,Matt McNabb,指出这一点).