位操作
在压缩和解压数据时,常常需要在小于一个字节的数量级上 进行数据操作。因此,在讨论各种数据压缩方法之前,首先必须熟悉一些对数据位进行的操作。这些操作非常重要,因为C语言本身只有一小步等内在的、不可分割的操作数。下面是介绍一些位操作的基础,和参阅博客:位操作基础篇之位操作全面总结
下面是自己对博客内容简单的总结。
- #include <stdio.h>
- #include <string.h>
- #include <memory.h>
- #include <stdbool.h>
- /*位运算小技巧*/
- /*1、判断奇偶*/
- #define IS_EVEN(n) {printf("number %d is:",(n));\
- (n) & 1 == 1?printf("奇数\n"):printf("偶数\n");}
- /*2、数据交换*/
- #define SWAP(a,b) { if (*a != *b){ \
- *a ^= *b;\
- *b ^= *a;\
- *a ^= *b;\
- }\
- }
- /*3、交换符号,就是将整数变为负数,负数变为整数*/
- #define SIGN_REVERSAL(n) (~(a) + 1)
- /*4、求绝对值*/
- #define ABS(n) ((n) >> 31 == 0?(n):(~(n) + 1))
- /*5、0到100中刷选素数方法*/
- #define MAXN 100
- bool flag[MAXN];
- int primes[MAXN/3 + 1],pi = 0;
- void getPrime_1()
- {
- int i,j;
- memset(flag,false,sizeof(flag));
- for(i = 2;i < MAXN; i++){
- if(!flag[i]){
- primes[pi++] = i;
- for(j = i; j < MAXN; j += i){
- flag[j] = true;
- }
- }
- }
- }
- void PrintfArray()
- {
- int i = 0;
- for(; i < pi; i++)
- printf("%d ",primes[i]);
- puts("");
- }
- /*位压缩筛选素数
- *其方法和上面的一样,只是在flag中用位来对应素数的位置
- *
- * */
- int flag_2[MAXN/32];
- void getPrime_2()
- {
- int i,j;
- pi = 0;
- memset(flag_2,false,sizeof(flag_2));
- for(i = 2;i < MAXN; i++){
- if(!((flag_2[i/32] >> (i%32)) & 1)){
- primes[pi++] = i;
- for(j = i; j < MAXN; j += i){
- flag_2[j/32] |= (1<<(j%32));
- }
- }
- }
- }
- int main()
- {
- IS_EVEN(20);
- int a = 10,b=20;
- printf("交换前:a = %d,b = %d\n",a,b);
- SWAP(&a,&b);
- printf("交换后:a = %d,b = %d\n",a,b);
- printf("a = %d,SIGN_REVERSAL(a) = %d\n",a,SIGN_REVERSAL(a));
- printf("ABS(a) = %d\n",ABS(a));
- puts("用筛素数法求100以内的素数");
- getPrime_1();
- PrintfArray();
- puts("用位运算筛素数法求100以内的素数");
- getPrime_2();
- PrintfArray();
- return 0;
- }
-
下面是数据压缩和解压中经常 遇到的位操作函数介绍
- /*bit.c*/
- #include <string.h>
- #include <stdio.h>
- /****************************************************************
- *获取bis中处于位置pos的位的状态。
- *返回值:相应位的状态:1or0。
- ***************************************************************/
- int bit_get(const unsigned char * bits, int pos)
- {
- unsigned char mask;
- int i;
- /*设置掩码*/
- mask = 0x80;
- for (i = 0; i < (pos % 8); i ++)
- mask = mask >> 1;
- /*获得当前位的数值*/
- return (((mask & bits[(int)(pos / 8)]) == mask )? 1:0);
- }
- /**********************************************************
- *设置bits中处于pos的位的状态(根据state的数值来设置)。
- *最左边位置位0,状态值必须为0或1;
- *无返回值
- * ******************************************************/
- void bit_set(unsigned char * bits, int pos, int state)
- {
- unsigned mask;
- int i;
- mask = 0x80;
- for (i = 0; i < (pos % 8); i ++)
- mask = mask >> 1;
- if (state)
- bits[pos/8] |= mask;
- else
- bits[pos/8] &= (~mask);
- return;
- }
- /********************************************************************
- *对bist1与bist2进行异或运算,结果保存到bitsx,
- *无返回值
- * *****************************************************************/
- void bit_xor(const unsigned char *bits1, const unsigned char *bits2, unsigned char *bitsx,int size)
- {
- int i;
- for (i = 0 ; i < size; i++){
- if(bit_get(bits1,1) != bit_get(bits2, 1)){
- bit_set(bitsx,i,1);
- } else {
- bit_set(bitsx,i,0);
- }
- }
- return;
- }
- /****************************************************************
- *将bits进行轮转,将位值向左移count位,操作完成后,处于最左端的
- *count位移动到最右端,而且其他位也相应的轮移
- * 无返回值
- * **************************************************************/
- void bit_rot_left(unsigned char *bits,int size, int count)
- {
- int fbit,
- lbit,
- i,
- j;
- if (size > 0){
- for ( j = 0; j < count; j++){
- for(i=0;i<=((size - 1)/8);i++){
- lbit = bit_get(&bits[i],0);
- if (i == 0)
- fbit = lbit;
- else
- bit_set(&bits[i - 1],7,lbit);
- bits[i] = bits[i] << 1;
- }
- bit_set(bits,size-1,fbit);
- }
- }
- }
- int main()
- {
- unsigned char a ='A' ;
- int i = 0;
- unsigned char b[]={'Z','B','C','D'};
- printf("获得‘A’的值是:");
- /*打印出来应该是01000001 0x41*/
- for(i=0;i<8;i++){
- printf("%d",bit_get(&a,i));
- }
- bit_set(&a,4,1);
- /*设置完的数值应该为01001001 0x49 'I'*/
- printf("\n ###%s() ,%d = %c\n",__FUNCTION__,a,a);
- bit_rot_left(b,9,2);
- printf("%s\n",b);
- }
其中对函数bit_rot_left()具体的功能有点模糊,测试几遍还是未能理解!有知道的麻烦给具体解答下! - 【本文转至】:http://blog.csdn.net/sjin_1314/article/details/8743888