C:位运算

本文转自:http://zhangjunhd.blog.51cto.com/113473/52734

1.负数表示-二类补数(twos complement)
一般使用二类补数表示负数,最左边一位为符号位.
将一个十进制负数转化为二进制符号数时,首先给这个数加1,然后取绝对值,再将其转换为二进制,最后对这个二进制求补.
[1]-5
[2]-4
[3]4
[4]0000 0100
[5]1111 1011
将一个负数从二进制转换为十进制,首先对其所有位求补,然后将结果转换为十进制,再改变其符号,最后再减1.
[1]1111 1011
[2]0000 0100
[3]4
[4]-4
[5]-5
使用二类补数表示数字时,用n位可存储的最大正数是2n-1-1,用n位可存储的最小负数-2n-1.
假设整数占32位(4字节),此时可存储的最大正数231-1,最小负数-231,而如果是无符号整数,即unsigned int,其表示范围为0至232-1.

2.按位与和按位或
按位与经常用于屏蔽一个数中的某些位,
word &= 0x1//除最右边4位外,其余位清零
按位或经常用于将某些位设定为1
word |= 0x1//将最右边4位设定为1

3.异或运算
异或运算可以交换两个值而不需要使用临时变量.

  1. /*exchange two integer values*/
  2. void swap(int* a, int* b)
  3. {
  4. *a ^= *b;
  5. *b ^= *a;
  6. *a ^= *b;
  7. }

如果某数与1进行异或运算,可以达到取反的效果,0^1=1,1^1=0.
这里假设机器的整型数长度为32位,对整数0的31位取反,得到最大整数.

  1. int main()
  2. {
  3. int a=0;
  4. printf("%i,%i",a,a ^ 0x7fffffff);
  5. return 0;
  6. }

4.几个经典的位运算函数
4.1求当前机器无符号整型最大长度

  1. /*the max length of unsigned int*/
  2. int int_size ()
  3. {
  4. unsigned int bits;
  5. int size = 0;
  6. bits = ~0;
  7. while ( bits ) {
  8. ++size;
  9. bits >>= 1;
  10. }
  11. return size;
  12. }


4.2移位运算

  1. /*a bit mover for unsigned int
  2. if n > 0 move left for n bits,else move right*/
  3. unsigned int bit_shift (unsigned int value,int n)
  4. {
  5. int intsize=int_size(); /*the length of unsigned int*/
  6. if(n>0 && n< intsize) /*move left*/
  7. value<<=n;
  8. else if (n<0 && n> -intsize) /*move right*/
  9. value>>=-n;
  10. else
  11. value=0;
  12. return value;
  13. }


4.3循环移位运算

  1. /*a bit rotate mover for unsigned int
  2. if n > 0 move left for n bits,else move right*/
  3. unsigned int bit_rotate (unsigned int value, int n)
  4. {
  5. unsigned int result,bits,intsize;
  6. intsize=int_size(); /*the length of unsigned int*/
  7. if(n > 0)
  8. n=n % intsize;
  9. else
  10. n=-(-n % intsize);
  11. if(n==0)
  12. result=value;
  13. else if(n >0 ){ /*move left*/
  14. bits=value >> (intsize-n);/*bits should be in the rightest*/
  15. result=value << n|bits;
  16. }else{ /*move right*/
  17. n=-n;
  18. bits=value << (intsize-n);/*bits should be in the leftest*/
  19. result=value >> n|bits;
  20. }
  21. return result;
  22. }


4.4返回无符号整型数value中从右起第p位的值

  1. /* get bit No.p(from right) of value to see if it is on */
  2. int bit_get (unsigned int value, int n)
  3. {
  4. int intsize=int_size(); /*the length of unsigned int*/
  5. if ( p < 0 || p > intsize-1 )/*out of range*/
  6. return 0;
  7. if ( (value >> p) & 1 )
  8. return 1;
  9. else
  10. return 0;
  11. }


4.5将无符号整型数value中从右起的第p位置1

  1. /* set bit No.p(from right) of value on */
  2. unsigned int bit_set (unsigned int value, int p)
  3. {
  4. int intsize=int_size(); /*the length of unsigned int*/
  5. if ( p < 0 || p > intsize-1 )/*out of range*/
  6. return 0;
  7. return value | (1 << p);
  8. }


4.6返回无符号整型数value中从第p位(右起)向右n位的值
[1]~(~0 << n)表示最右边n位全为1;
[2]value >> (p+1-n)表示将目标位字段移至最右端;

  1. /*get n bits of value at position p(from right) */
  2. unsigned bits_get (unsigned int value, int p, int n)
  3. {
  4. int intsize=int_size(); /*the length of unsigned int*/
  5. if ( n < 0 || p < 0 || p + n > intsize )
  6. return 0;
  7. return(value >> (p+1-n)) & ~(~0 << n);
  8. }


4.7将无符号整型数value中从第p位(右起)向右n位设置为y最右边n位的值
[1]~(~0 << n)表示最右边n位全为1;
[2](~(~0 << n) << (p+1-n)表示将这n个1位左移至位置p;
[3]~(~(~0 << n) << (p+1-n))表示将从位置p开始的n位设置零,其余位设置一;
[4]unsigned tar=bits_get(y,n-1,n);取出y的低n位;

  1. /*set n bits of value at position p(from right) with bits of y*/
  2. unsigned bits_set (unsigned value, int p, int n, unsigned int y)
  3. {
  4. int intsize=int_size(); /*the length of unsigned int*/
  5. if ( n < 0 || p < 0 || p + n > intsize )
  6. return 0;
  7. unsigned tar=bits_get(y,n-1,n);
  8. return (value & ~(~(~0 << n) << (p+1-n))) | tar;
  9. }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章