/*******************************************************************
Copyright(c) 2016, Tyrone Li
All rights reserved.
*******************************************************************/
// 作者:TyroneLi
//
/*
Q:
统计二进制中1的个数
实现一个函数,输入一个整数,输出二进制中的1的个数,
例如把9表示成二进制1001,有两位是1,因此输出2.
S:
1.循环右移一位,然后跟1进行与运算,不过这样会导致出现死循环,因为右移,对于负数前面会补1.
2.循环左移1一位,与整数进行与运算。
3.循环与整数和整数减1之后的结果,并将与结果重新循环;因为每次减一操作,都会导致最后边一位1变为0.
同时将该位的后面所有的数均变为0.
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
int numberOf1_one(int n)
{
if(n < 0)
return -1;
int count = 0;
int flag = 1;
while(n)
{
if(n & 1)
++count;;
n = n >> 1;
}
return count;
}
int numberOf1_two(int n)
{
unsigned int flag = 1;
int count = 0;
while(flag)
{
if(flag & n)
++count;
flag <<= 1;
}
return count;
}
int numberOf1_three(int n)
{
int count = 0;
while(n)
{
++count;
n = n & (n-1);
}
return count;
}
/* 统计整数中0的个数,1 */
int numberOf0_one(int n)
{
int bits_count = 8*(sizeof(n));
int count_0 = numberOf1_three(n);
return (bits_count - count_0);
}
/*
Q:
用一条语句判断一个整数是不是2的整数次方.
S:
如果一个整数是2的整数次方,那么其减去1得到的整数就是跟原来整数每个位数字相反,即
两个数与结果中1的个数为0.
*/
bool isNum2NumMi(int n)
{
if(n <= 0)
return false;
int n_minus1 = n - 1;
int n_tmp = n & n_minus1;
int count_1 = numberOf1_three(n_tmp);
return (count_1 == 0)? true:false;
}
/*
Q:
输入两个整数m和n,计算需要改变m的二进制中多少位才能得到n.
S:
假设m和n分别是1011和1000,那么他们相同的位进行异或操作得到的就是0,不同的位异或结果就是1,
然后统计两个数异或结果中的1的位数,即是两个数的不同的位数。
*/
int calc_DiffBits(int m, int n)
{
int m_n = m ^ n;
int count_1 = numberOf1_three(m_n);
return count_1;
}
void test_numberOf1()
{
std::cout << "test number of 1 in func 1" << std::endl;
std::cout << " num of 1 in 0 binary format: " << numberOf1_one(0) << std::endl;
std::cout << " num of 1 in 1 binary format: " << numberOf1_one(1) << std::endl;
std::cout << " num of 1 in 5 binary format: " << numberOf1_one(5) << std::endl;
std::cout << " num of 1 in 8 binary format: " << numberOf1_one(8) << std::endl;
std::cout << " num of 1 in 15 binary format: " << numberOf1_one(15) << std::endl;
std::cout << " num of 1 in 63 binary format: " << numberOf1_one(63) << std::endl;
std::cout << " num of 1 in -1 binary format: " << numberOf1_one(-1) << std::endl;
std::cout << " num of 1 in -5 binary format: " << numberOf1_one(-5) << std::endl;
std::cout << " num of 1 in -8 binary format: " << numberOf1_one(-8) << std::endl;
std::cout << " num of 1 in -15 binary format: " << numberOf1_one(-15) << std::endl;
std::cout << " num of 1 in -63 binary format: " << numberOf1_one(-63) << std::endl;
}
void test_numberOf2()
{
std::cout << "test number of 1 in func 1" << std::endl;
std::cout << " num of 1 in 0 binary format: " << numberOf1_two(0) << std::endl;
std::cout << " num of 1 in 1 binary format: " << numberOf1_two(1) << std::endl;
std::cout << " num of 1 in 5 binary format: " << numberOf1_two(5) << std::endl;
std::cout << " num of 1 in 8 binary format: " << numberOf1_two(8) << std::endl;
std::cout << " num of 1 in 15 binary format: " << numberOf1_two(15) << std::endl;
std::cout << " num of 1 in 63 binary format: " << numberOf1_two(63) << std::endl;
std::cout << " num of 1 in -1 binary format: " << numberOf1_two(-1) << std::endl;
std::cout << " num of 1 in -1 binary format: " << numberOf1_two(-1) << std::endl;
std::cout << " num of 1 in -5 binary format: " << numberOf1_two(-5) << std::endl;
std::cout << " num of 1 in -8 binary format: " << numberOf1_two(-8) << std::endl;
std::cout << " num of 1 in -15 binary format: " << numberOf1_two(-15) << std::endl;
std::cout << " num of 1 in -63 binary format: " << numberOf1_two(-63) << std::endl;
std::cout << " num of 1 in 0x7FFFFFFF binary format: " << numberOf1_two(0x7FFFFFFF) << std::endl;
std::cout << " num of 1 in 0x80000000 binary format: " << numberOf1_two(0x80000000) << std::endl;
std::cout << " num of 1 in 0xFFFF binary format: " << numberOf1_two(0xffff) << std::endl;
std::cout << " num of 1 in 0xFFFFFFFF binary format: " << numberOf1_two(0xffffffff) << std::endl;
}
void test_numberOf3()
{
std::cout << "test number of 1 in func 1" << std::endl;
std::cout << " num of 1 in 0 binary format: " << numberOf1_three(0) << std::endl;
std::cout << " num of 1 in 1 binary format: " << numberOf1_three(1) << std::endl;
std::cout << " num of 1 in 5 binary format: " << numberOf1_three(5) << std::endl;
std::cout << " num of 1 in 8 binary format: " << numberOf1_three(8) << std::endl;
std::cout << " num of 1 in 15 binary format: " << numberOf1_three(15) << std::endl;
std::cout << " num of 1 in 63 binary format: " << numberOf1_three(63) << std::endl;
std::cout << " num of 1 in -1 binary format: " << numberOf1_three(-1) << std::endl;
std::cout << " num of 1 in -1 binary format: " << numberOf1_three(-1) << std::endl;
std::cout << " num of 1 in -5 binary format: " << numberOf1_three(-5) << std::endl;
std::cout << " num of 1 in -8 binary format: " << numberOf1_three(-8) << std::endl;
std::cout << " num of 1 in -15 binary format: " << numberOf1_three(-15) << std::endl;
std::cout << " num of 1 in -63 binary format: " << numberOf1_three(-63) << std::endl;
std::cout << " num of 1 in 0x7FFFFFFF binary format: " << numberOf1_three(0x7FFFFFFF) << std::endl;
std::cout << " num of 1 in 0x80000000 binary format: " << numberOf1_three(0x80000000) << std::endl;
std::cout << " num of 1 in 0xFFFF binary format: " << numberOf1_three(0xffff) << std::endl;
std::cout << " num of 1 in 0xFFFFFFFF binary format: " << numberOf1_three(0xffffffff) << std::endl;
}
void test_numberOf0()
{
std::cout << "test number of 0 in func 1" << std::endl;
std::cout << " num of 0 in 0 binary format: " << numberOf0_one(0) << std::endl;
std::cout << " num of 0 in 1 binary format: " << numberOf0_one(1) << std::endl;
std::cout << " num of 0 in 5 binary format: " << numberOf0_one(5) << std::endl;
std::cout << " num of 0 in 8 binary format: " << numberOf0_one(8) << std::endl;
std::cout << " num of 0 in 15 binary format: " << numberOf0_one(15) << std::endl;
std::cout << " num of 0 in 63 binary format: " << numberOf0_one(63) << std::endl;
std::cout << " num of 0 in -1 binary format: " << numberOf0_one(-1) << std::endl;
std::cout << " num of 0 in -5 binary format: " << numberOf0_one(-5) << std::endl;
std::cout << " num of 0 in -8 binary format: " << numberOf0_one(-8) << std::endl;
std::cout << " num of 0 in -15 binary format: " << numberOf0_one(-15) << std::endl;
std::cout << " num of 0 in -63 binary format: " << numberOf0_one(-63) << std::endl;
}
void test_isNum2NumMi()
{
std::cout << "test isNum2NumMi " << std::endl;
std::cout << "num 0 is 2^n? " << isNum2NumMi(0) << std::endl;
std::cout << "num 1 is 2^n? " << isNum2NumMi(1) << std::endl;
std::cout << "num 2 is 2^n? " << isNum2NumMi(2) << std::endl;
std::cout << "num 4 is 2^n? " << isNum2NumMi(4) << std::endl;
std::cout << "num 5 is 2^n? " << isNum2NumMi(5) << std::endl;
std::cout << "num 11 is 2^n? " << isNum2NumMi(11) << std::endl;
std::cout << "num 1/2 is 2^n? " << isNum2NumMi(1/2) << std::endl;
std::cout << "num 1/8 is 2^n? " << isNum2NumMi(1/8) << std::endl;
std::cout << "num 512 is 2^n? " << isNum2NumMi(512) << std::endl;
std::cout << "num -2 is 2^n? " << isNum2NumMi(-2) << std::endl;
}
void test_calc_DiffBits()
{
std::cout << "test calc_DiffBits" << std::endl;
std::cout << "num 0 and 1 differenct bits count: " << calc_DiffBits(0, 1) << std::endl;
std::cout << "num 1 and -1 differenct bits count: " << calc_DiffBits(1, -1) << std::endl;
std::cout << "num 16 and 0 differenct bits count: " << calc_DiffBits(16, 0) << std::endl;
std::cout << "num -1 and -2 differenct bits count: " << calc_DiffBits(-1, -2) << std::endl;
std::cout << "num 64 and 2 differenct bits count: " << calc_DiffBits(64, 2) << std::endl;
std::cout << "num 0x11011 and 0x10001 differenct bits count: " << calc_DiffBits(0x11011, 0x10001) << std::endl;
std::cout << "num 0x11111 and 0x10001 differenct bits count: " << calc_DiffBits(0x11111, 0x10001) << std::endl;
std::cout << "num 0x11000 and 0x00101 differenct bits count: " << calc_DiffBits(0x11000, 0x00101) << std::endl;
}
int main(int argc, char**argv)
{
test_numberOf1();
test_numberOf2();
test_numberOf3();
test_numberOf0();
test_isNum2NumMi();
test_calc_DiffBits();
return 0;
}