首先可以把unsigned int数中的1的个数与0的个数改变与计算的实现:
</pre><pre name="code" class="cpp">/**********************************************************************
* * Copyright (c)2015,WK Studios
* * Filename: A.h
* * Compiler: GCC vc 6.0
* * Author:WK
* * Time: 2015 2 7
* **********************************************************************/
#include<iostream>
using namespace std;
#include <assert.h>
void Set_Bit(size_t * Int_Dat,size_t Posi,bool ch )
{
if(ch)
{
*Int_Dat |= (0x01<<(Posi-1));
}
else
{
*Int_Dat &= ~(0x01<<(Posi-1));
}
}
size_t Cal_Bit1(size_t d)
{
size_t n=0;
while(d )
{
if(d & 0x01)
{
++n;
}
d/=2;
}
return n;
}
size_t Cal_Bit0(size_t d)
{
size_t n=0;
while(d)
{
if(!(d%2))
{
++n;
}
d/=2;
}
return n;
}
size_t Cal_B1(size_t d)
{
size_t n=0;
while(d)
{
++n;
d&=(d-1);//末尾一位置0
}
return n;
}
size_t Cal_B0(size_t d)
{
size_t n=0;
while((d+1))
{
++n;
d |= (d+1);//末尾一位置1
}
return n;
}
void main()
{
cout<<"-----计算无符号整型中0或者1的个数-----\n";
unsigned int m=15;
cout<<"原数据:"<<m<<endl;
cout<<"0个数:"<<Cal_Bit0(m)<<endl;//这种计算忽略了前边的零
cout<<"1个数:"<<Cal_Bit1(m)<<endl;
cout<<"0个数:"<< Cal_B0(m)<<endl;//计算在32位中的零
cout<<"1个数:"<< Cal_B1( m)<<endl;
cout<<"-----无符号整型指定位置0或者置1-----\n";
unsigned int d=4;
cout<<"原数据:"<<d<<endl;
Set_Bit( &d, 2,1 );
cout<<"指定位置置1后:"<<d<<endl;
Set_Bit( &d, 2,0 );
cout<<"指定位置置0后:"<<d<<endl;
}
用类实现在无符号整型指定的位置赋1:
#include<iostream>
using namespace std;
#include <assert.h>
#define FSIZE 32
#define TRUE 1
#define FALSE 0
class flags
{
unsigned char f[FSIZE];
public:
flags();
void set(int i);
void clear(int i );
int read(int i);
int size();
};
flags::flags()
{
memset(f,FALSE,FSIZE);//初始化为FSIZE位全是0
}
void flags::set(int i)
{
assert(i>=0 && i<FSIZE);
f[i]=TRUE;
}
void flags::clear(int i)
{
assert(i>=0 && i<FSIZE);
f[i]=FALSE;
}
int flags::read(int i)
{
assert(i>=0 && i<FSIZE);
return f[i];
}
int flags::size()
{
return FSIZE;
}
void main()
{
flags f1;
for(int i=0;i<f1.size();++i)
{
if(i%3==0)//在可以被三整除的位置赋为1
f1.set(i);
}
for(int j=0;j<f1.size();++j)
{
cout<<f1.read(j)<<" ";
}
cout<<endl;
}
更加复杂的实现对无符号整型中二进制位的修改:
/**********************************************************************
* * Copyright (c)2015,WK Studios
* * Filename: A.h
* * Compiler: GCC vc 6.0
* * Author:WK
* * Time: 2015 2 7
* **********************************************************************/
#include<iostream>
using namespace std;
#include<assert.h>
#include<limits.h>
const unsigned char highbit=1 << (CHAR_BIT-1);
class BitVector
{
public:
BitVector();
BitVector(unsigned char* init,int size=8);
BitVector(char* Binary);//可以使用"000101010"字符串来初始化
~BitVector();
void set(int init);
void clear(int bit);
int read(int bit);
void bits(int sz);
int bits();
void print(const char* msg="");//缺省的常量字符串仍然在常量区里保存
private:
unsigned char* Bytes;
int Bits,NumBytes;//比特位和字节数
};
BitVector::BitVector()//把所有的变量赋零
{
NumBytes=0;
Bits=0;
Bytes=0;
}
BitVector::BitVector(unsigned char* init,int size)//分配内存并且初始化位数
{
NumBytes=size;//字节数 11110000
Bits=NumBytes*CHAR_BIT;//总共的比特位数
Bytes=(unsigned char*)calloc(NumBytes,1);//void *calloc(size_t n, size_t size);
//分配NumBytes个1字节的空间
assert(Bytes);
if(init==NULL )
{
return;
}
for(int index=0;index<NumBytes;++index)
{
for(int offset=0;offset<CHAR_BIT;++offset)
{
if(init[index] & (highbit>>offset))
set(index * CHAR_BIT+offset);
}
}
}
BitVector::BitVector(char* Binary)
{ //"1111010010"
assert(Binary);
Bits=strlen(Binary);
NumBytes=Bits/CHAR_BIT;//字节数
//不足8比特位的也分配一个字节
if(Bits%CHAR_BIT)
NumBytes++;
Bytes=(unsigned char*)calloc(NumBytes,1);
assert(Bytes);
for(int i=0;i<Bits;++i)
{
if(Binary[i]=='1')
set(i);
}
}
BitVector::~BitVector()
{
free(Bytes);
}
void BitVector::set(int bit)
{
assert(bit>=0 && bit<Bits);
int index=bit/CHAR_BIT;
int offset=bit % CHAR_BIT;
unsigned char mask =(1<<offset);
Bytes[index] |= mask;
}
int BitVector::read(int bit)
{
assert(bit>=0 && bit<Bits);
int index=bit/CHAR_BIT;
int offset=bit % CHAR_BIT;
unsigned char mask =(1<<offset);
return Bytes[index] & mask;//其实可以只用一句就结局问题,但是程序的可读性太差
}
void BitVector::clear(int bit)
{
assert(bit>=0 && bit<Bits);
int index=bit/CHAR_BIT;
int offset=bit % CHAR_BIT;
unsigned char mask =~(1<<offset);
Bytes[index] &= mask;
}
int BitVector:: bits()
{
return Bits;
}
void BitVector::bits(int size)
{
int oldsize =Bits;
Bits=size;
NumBytes=Bits/CHAR_BIT;
if(Bits%CHAR_BIT)
NumBytes++;
void* V=realloc(Bytes,NumBytes);
assert(V);
Bytes=(unsigned char*)V;
for(int i=oldsize;i<Bits;++i)
{
clear(i);
}
}
void BitVector::print(const char* msg)
{
puts(msg);
for(int i=0;i<Bits;i++)
{
if(read(i))
putchar('1');
else
putchar('0');
if((i+1)%CHAR_BIT == 0)
putchar(' ');
}
putchar('\n');
}
void main()
{
unsigned char b[]={0x0f,0xff,0xf0,
0xAA,0x78,0x11};
// unsigned char b[]={'a','b','c','d','e','f'};
BitVector bv1(b,sizeof (b)/sizeof (*b)),
bv2("10010100111100101010001010010010101");
bv1.print("bv1 before modification");
for(int i=36;i<bv1.bits();++i)
{
bv1.clear(i);
}
bv1.print("bv1 after modification");
bv2.print("bv2 after modification");
for(int j=bv2.bits()-10;j<bv2.bits();++j)
{
bv2.clear(j);
}
bv2.set(30);
bv2.print("bv2 after modification");
bv2.bits(bv2.bits()/2);
bv2.print("bv2 cut in half");
bv2.bits(bv2.bits()+10);
bv2.print("bv2 grown by 10");
BitVector bv3((unsigned char*)0);
}