十进制整数如何利用位操作求的该整数的二进制中1的个数
2012-03-16 20:46
232 查看
此题可有多种方法,大概可以分为两种:一种是制表法,另一种就是通俗的数学方法。其中数学方法中一个简单明了的方法就是利用一个while循环,采用按位与的方式。代码如下:
但是此代码有一个致命的缺陷,就是当输入数字是负数时,输出结果都是0。改进方案如下:
此思路较为清晰,方法就是每次都查看该十进制数末尾是否为1,如果是count++,如果不是,将最后一位右移。然后再比较下一位。
另一种比较难理解的方法是:
采用打表法的代码如下:
#include<iostream> using namespace std; int main() { int a; int count; while(cin>>a&&a) { count=0; while(a>0) { a=(a-1)&a; count++; } cout<<count<<endl; } return 0; }
但是此代码有一个致命的缺陷,就是当输入数字是负数时,输出结果都是0。改进方案如下:
#include<iostream> using namespace std; int main() { int a; int count; while(cin>>a&&a) { count=0; while(a) { if(a&1==1) { count++; } a=a>>1; } cout<<count<<endl; } return 0; }
此思路较为清晰,方法就是每次都查看该十进制数末尾是否为1,如果是count++,如果不是,将最后一位右移。然后再比较下一位。
另一种比较难理解的方法是:
#include<iostream> using namespace std; int fun(int x) { x = (0x55555555 & x) + ((0xAAAAAAAA & x)>>1); x = (0x33333333 & x) + ((0xCCCCCCCC & x)>>2); x = (0x0F0F0F0F & x) + ((0xF0F0F0F0 & x)>>4); x = (0x00FF00FF & x) + ((0xFF00FF00 & x)>>8); x = (0x0000FFFF & x) + ((0xFFFF0000 & x)>>16); return x; } int main() { int a; int count; while(cin>>a&&a) { cout<<fun(a)<<endl; } return 0; }
采用打表法的代码如下:
#include<iostream> #include<cmath> #include<ctime> using namespace std; int f1(int n,int *a) {//右移四位,与15进行与运算并查表 int i=0; i+=a[n&15]; i+=a[n>>4&15]; i+=a[n>>8&15]; i+=a[n>>12&15]; i+=a[n>>16&15]; i+=a[n>>20&15]; i+=a[n>>24&15]; i+=a[n>>28&15]; return i; } int f3(int n,int *a) {//右移八位,与255进行与运算并查表 int i=0; i+=a[n&255]; i+=a[n>>8&255]; i+=a[n>>16&255]; i+=a[n>>24&255]; return i; } int main(void) { // 计算一整数对应二进制数的1的个数 int i,N; int a[256]= {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4, 2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6, 4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5, 3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8}; //0-255对应二进制数含1的个数 int b[16]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; //0-15对应二进制数含1的个数 N=20000000; double start,finish; srand((unsigned int)time(NULL)); start=clock(); for(i=0;i<N;++i) { f1(i,b); } cout<<i<<endl; finish=clock(); cout<<(finish-start)/CLOCKS_PER_SEC<<endl; start=clock(); for(i=0;i<N;++i) { f3(i,a); } cout<<i<<endl; finish=clock(); cout<<(finish-start)/CLOCKS_PER_SEC<<endl; return 0; }
#include<iostream> using namespace std; int fun(int x) { x = (0x55555555 & x) + ((0xAAAAAAAA & x)>>1); x = (0x33333333 & x) + ((0xCCCCCCCC & x)>>2); x = (0x0F0F0F0F & x) + ((0xF0F0F0F0 & x)>>4); x = (0x00FF00FF & x) + ((0xFF00FF00 & x)>>8); x = (0x0000FFFF & x) + ((0xFFFF0000 & x)>>16); return x; } int main() { int a; int count; while(cin>>a&&a) { cout<<fun(a)<<endl; } return 0; }
相关文章推荐
- C++ cout利用控制符dec、hex和oct,分别输出十进制、十六进制和八进制显示整数
- 如何将十进制转换为二进制、八进制、十六进制
- 整数十进制转换成二进制
- Java中如何得到一个整型数的二进制形式(十进制转化成二进制)
- 【填空题】二进制串转十进制整数
- 利用进位表计算十进制到二进制的转换
- HDU-2051 Bitset 进制转化(十进制整数向二进制整数转化)
- 一个整数的二进制序列倒置后再转换为十进制的整数
- 十进制整数转换二进制
- 输入一个十进制整数,统计其中二进制1的个数
- C#中如何实现二进制、十进制、十六进制的互转
- 如何求整数A和B的二进制表示中有多少位不同?
- 十进制有限小数如何以二进制保存而不会变成无限小数
- 十进制整数转二进制的各种实现和思考
- C++利用栈进行十进制与二进制的转换
- 十进制整数,计算对应的二进制数包含多少个1,用位操作
- C语言整数十进制按照二进制形式输出程序
- Verilog实现整数与小数部分的二进制转化为十进制
- 如何将十六进制转换为、二进制、八进制、十进制
- c#如何将一个整数转换二进制,并进行位运算