位操作
符号 | 名称 | 演示 |
---|---|---|
& | 与 | 1 & 1 = 1 1 & 0 = 0 0 & 0 = 0 |
| | 或 | 1|1 = 1 1|0 = 1 0|0 = 0 |
^ | 异或 | 1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 0 = 0 |
~ | 非 | ~1 = 0 ~0 = 1 |
<< | 左移 | 10101 << 2 =10100(相当于乘2) |
>> | 右移 | 10101 >> 2 =00101(相当于除2) |
常见函数
set_bit
1 | // 给position位设置为1 |
clear_bit
1 | //给position位设置为0 |
flip_bit
1 | //翻转position位的值 |
is_bit_set
1 | //判断position位是否为bit(1) |
modify_bit(见补码)
1 | //state 为 1 是set_bit ;state 为 0 时clear_bit |
补码(二补数)
补码用来表示负数的
表示
补码使用有符号第一位表示正负,1为负 0为正,所以8有符号位数范围+-127,无符号位数255-0,无符号位数在C#中UInt32
代表无符号32位
十进制值 | 二进制(二进制补码表示) | 二补(2 - n)2 |
---|---|---|
0 | 0000 0000 | 0000 0000 |
1 | 0000 0001 | 1111 1111 |
2 | 0000 0010 | 1111 1110 |
126 | 0111 1110 | 1000 0010 |
127 | 0111 1111 | 1000 0001 |
-128 | 1000 0000 | 1000 0000 |
-127 | 1000 0001 | 0111 1111 |
-126 | 1000 0010 | 0111 1110 |
-2 | 1111 1110 | 0000 0010 |
-1 | 1111 1111 | 0000 0001 |
为什么使用补码
二补数系统的最大优点是可以在加法或减法处理中,不需因为数字的正负而使用不同的计算方式。只要一种加法电路就可以处理各种有号数加法,而且减法可以用一个数加上另一个数的二补数来表示,因此只要有加法电路及二补数电路即可完成各种有号数加法及减法,在电路设计上相当方便。
如何进行表示
-1 原码:0000 0001
反码:1111 1110
补码=反码+1:1111 1111
一种简易的方式,可以找出二进位数字的二补数
先由最低位元开始找。
若该位元为0,将二补数对应位元填0,继续找下一位元(较高的位元)。
若找到第一个为1的位元,将二补数对应位元填1。
将其馀未转换的位元进行位元反相,将结果填入对应的二补数。
以0011 1100为例(图中的^表示目前转换的数字,-表示还不确定的位数):
原数字 补码
0011 1100 —- —0(此位元为0)
^
0011 1100 —- –00(此位元为0)
^
0011 1100 —- -100(找到第1个为1的位元)
^
0011 1100 1100 0100(其馀位元直接反相)
^
因此其结果为1100 0100
一些位操作
一些提示
C#中不能直接将一串二进制数赋值给int32,可以用一下转换
Convert.ToInt32("1111",2)
1111的二进制,即15 int32类型
Convert.ToString(15,2)
15的二进制字符串,”1111“
是否为偶数
1 | static bool is_even(int i) |
返回有多少位不同
1 | static int diff_bit(int a,int b) |
四舍五入2的幂数
1 | static int roundUpToNextPowerOfTwo(int x) |
交换两个数,效率比附tmp值低
1 | static void swapXor(ref int a,ref int b) |
取绝对值
1 | static int myabs(int a) |