位运算操作相关

来源:互联网 发布:淘宝入驻平台 编辑:程序博客网 时间:2024/05/18 11:02

    位操作

    在压缩和解压数据时,常常需要在小于一个字节的数量级上 进行数据操作。因此,在讨论各种数据压缩方法之前,首先必须熟悉一些对数据位进行的操作。这些操作非常重要,因为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  100bool 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()具体的功能有点模糊,测试几遍还是未能理解!有知道的麻烦给具体解答下!


原创粉丝点击