【C/C++】计算二进制中的1的简单方法

一、什么是二进制

众所周知,计算机存取一个数都是以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;
}

然而,高级版并不是最优的。

什么?感觉还不够深?

偷偷给我塞一块钱我告诉你偷笑
 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值