关于无符号整型数中1的个数与0的个数的改变与计算引发的思考

首先可以把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);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 23:14:13

关于无符号整型数中1的个数与0的个数的改变与计算引发的思考的相关文章

翻转无符号整型数据的比特位

[问题:给定无符号整型数据,需要你翻转它的比特位(依中心镜像翻转)] 这个问题有很多解决方法,这里介绍利用异或(xor)运算解决这个问题的小技巧. 提示:怎样交换第i位比特和第j位比特数据呢?试着想想怎样用异或(xor)运算实现. 异或运算技巧: 实现翻转我们需要将这个数据的前n/2(假设数据有效位数为n,二进制)有效位和后n/2有效位进行交换.写一个函数swapBits(i, j),用来交换第i位和第j位bit. 复习一下异或运算: 0 ^ 0 == 0 1 ^ 1 == 0 0 ^ 1 ==

v.size() return size_t not int 返回无符号整型数

In the C++ STL, the vector size() function return size_t, which is unsigned int, not int. So imagine this, define an empty vector<int> v, and v.size() should be 0, and you have a for loop, and has an end condition is v.size() - 1, which is 429496729

uint8是8位无符号整型,uint16是16位无符号整型。

整型有无符号(unsigned)和有符号(signed)两种类型,在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned.在一些不可能取值为负数的时候,可以定义为unsigned,在一些底层的嵌入式编程的数据一般都是无符号. 向左转|向右转 扩展资料: 负数时的有符号整型和无符号整型的转换 当执行一个运算时(如这里的a>b),如果它的一个运算数是有符号的而另一个数是无符号的,那么C语言会隐式地将有符号 参数强制类型为无符号数,并

有符号和无符号整型数字

8位无符号整型:0 -> 25511111111     255...10000000     12801111111     127...00000000       0 8位有符号整型:-128 -> 12701111111    127...00000000      011111111     -1        取反加一...10000000   -128        取反加一

[C/C++]如何将一个无符号整型所有数据位置为1

正解「x = -1;」 -1超出无符号整型x的表达范围,根据标准(C++11 section 4.7.2),-1将被转化为2^n-1(n为x的bit数). 不正解 「x = 0xFFFFFFFF;」 这只适用于32bit整型. 不正解「x = ~0;」 这个被很多书认定为「标准答案」的解答也是错的.C/C++标准支持原码/反码/补码三种负数表示形式,只有在补码环境下才会得到正确结果.(例如在反码下,~0将得到-0,-0转为无符号仍然是0) 那么x = ~0u呢? 仍然是错的.根据标准(C++11

【C语言位运算的应用】如何按bit位翻转一个无符号整型

其实现思路如下: 将目标数值进行末尾比特位摘取,将所摘取的bit位放到一个相同类型的末尾,目标数值bit位右移,相同类型bit位左移. C语言的位运算符:     实现代码如下: #include <stdio.h>//按位翻转一个无符号整形 unsigned int reverse_bit(unsigned int value) { unsigned int num = 0; int i = 0; for (i = 1; i < 32; i++) { num += value &

无符号整型指定比特位置1

将无符号数的指定比特进行置1.输入数字n(31bit,无符号整形),置为数m(0<=m<=31). 输入:无符号数,指定bit位 输出:指定的bit位被置1的值 例如:输入 891 7 输出 1019 1 #include <stdio.h> 2 #include <stdlib.h> 3 int main(void) 4 { 5 unsigned int c, tmp; 6 int d; 7 while (1) 8 { 9 scanf("%d%d"

无符号整型与有符号整型相运算规则

有符号数和无符号数运算的时候,有符号数会自动向无符号数转换 1 #include<iostream> 2 #include<ctime> 3 #include <stdio.h> 4 #include<cstring> 5 #include<cstdlib> 6 #include <map> 7 #include <string> 8 using namespace std; 9 10 #if TEST 11 int ma

无符号整型unsigned int、unsigned long、usigned long long、size_t比较和格式控制

位数比较 由于数据的长度和平台相关,所以基于 64 位系统比较. Windows Linux unsigned int 32 bits/4294967295 32 bits unsigned long 32 bits 64 bits/18446744073709551615 unsigned long long 64 bits 64 bits size_t 32 bits 64 bits 可以看到,size_t 和 unsigned long 比较同步.另外 ssize_t 和 size_t 的