一、什么是二进制
众所周知,计算机存取一个数都是以0,1的方法存取的。
比如一个整形的1,在内存里就是00000000 00000000 00000000 00000001
那么-1呢,不会以为是10000000 00000000 00000000 00000001
我告诉你,这不对。
计算机存取数据是以二进制补码的形式存储的
正数的原码、反码和补码是一样的
负数却不是
-1的原码是 10000000 00000000 00000000 00000001
反码 (符号位不变,其他按位取反)11111111 11111111 11111111 11111110
补码(反码基础上+1) 11111111 11111111 11111111 11111111
二、这次,就让我们来求一个 int型(32个BIT位)的正数中二进制1的个数
(1)基础版->利用数学方法求解
计算方法:
基础版代码块:
#include<stdio.h>
int count_one_bits(int value)
{
int count = 0;
while( value != 0 )
{
if(value%2 == 1)
count++;
value /= 2;
}
return count;
}
int main()
{
unsigned value = 0;
int count = 0;
printf("请输入一个正整数:");
scanf("%d",&value);
count = count_one_bits(value);
printf("这个数二进制的1有%d个",count);
return 0;
}
解析:
好了,代码在这块,运行一下如何?
如果你真的运行了的话,除了试试正数之外,还应该试试负数
你试试-1。程序不能输出32吧。
当然了,你让-1%2?
(2)强化版->运用右移操作符">>"
方法:
强化版代码块:
#include<stdio.h>
int main()
{
int value = 0;
int count = 0;
printf("请输入一个整数:");
scanf("%d",&value);
int i = 0;
for( i = 0; i<32 ;i++)
{
if(value&1==1)
count++;
value = value >> 1;
}
printf("count = %d",count);
return 0;
}
解析:
不错,负数可以计算了,已经达到我们想要的目的
可是再仔细看一看,不管是几她都要循环32次!
可不可以再优化呢?
(3)高级版->利用value = (value & (value - 1))
方法:
高级版代码块:
#include<stdio.h>
int main()
{
int value = 0;
int count = 0;
printf("请输入一个整数:");
scanf("%d",&value);
while(value != 0)
{
count++;
value = (value & (value-1));
}
printf("count = %d",count);
return 0;
}
解析:
如果这几个刚刚好才能看懂的话,
那么你写出这样的代码,就可以了。
(4)机智如我版->隐式强制类型转换(int 转为 unsigned)
方法:
“机智如我版”代码块:
#include<stdio.h>
int count_one_bits(unsigned int value)
{
int count = 0;
while( value != 0 )
{
if(value%2 == 1)
count++;
value /= 2;
}
return count;
}
int main()
{
unsigned value = 0;
int count = 0;
printf("请输入一个整数:");
scanf("%d",&value);
count = count_one_bits(value);
printf("这个数二进制的1有%d个",count);
return 0;
}
然而,高级版并不是最优的。
什么?感觉还不够深?
偷偷给我塞一块钱我告诉你