这个题是自己总结的。看着简单,看看它的分析过程,就会发现小处皆学问。
求一个数的二进制,最简单的方式就是直接计算:
void getBinary1(unsigned int x)
{
int a[32]={0};
int i=0;
do
{
a[i++]=x&0X01;
x=x>>1;
}
for(i=i-1;i>=0;--i)
cout<<a[i];
cout<<endl;
}
void getBinary2(unsigned int x)
{
if(x&0X01!=0)
getBinary2(x>>1);
cout<<x&0X01;
}
/*
//错误代码
void getBinary3( int x){
if(x/2!=0)
getBinary3(x/2);
cout<<abs(x%2);
}
上述两个程序都比较简单,第一个是非递归实现,第二个是递归实现。
问题很明显了,对于第一个程序,求2进制的过程(包括其他8,16进制),需要将取模的结果反转,故一定需要开辟内存的空间需要来保存中间取模的值; 对于第二个程序,因为是递归,故效率较低; 另外大家注意,这两个程序的参数都是无符号整形的,为什么呢? 如果你用负数进行计算,负数/2结果是-1 和0,不是你想象中的0和1,当然不对了。 你可能会说,输出abs(x%2),貌似把-1,0变成了1和0,但是你要知道负数在内存中是以补码的形成存放的,高位都是1,所以通过abs不对 的。
例如: -3.
二进制形式应该是:11111111111111111111111111111101 , 而通过上述getBinary3得到的结果是 11;
那么对于负数的情况应该怎么办呢? 只需要将负数转化为对应的unsigned整数即可,最高位的1原来为符号标志位,现在是无符号数的最高有效位,其他的和处理正数一样。
例如:
求-3的二进制表示,只需要:
int x=-3;
unsigned t=unsigned(x)
getBinary1(unsigned(t) 或者 getBinary2(t)
第二种思路比较朴素,直接判断每一位,由于惯性思维一般不容易想到,但这个方法值得推荐。优点是不需要做复杂的判断,直观,正负通用,不需要额外的空间,更不递归了。缺点就是需要循环32次,对于64位则需要64次,但是这点代价是微不足道的。
bool isFirst=false;
for(int i=1;i<=32;++i)
{
temp=x<0 ? 1:0;
if( temp!=0)
isFirst=true;
if(isFirst)
cout<< temp;
x=x<<1;
}
cout<<endl;