二进制运算理解及在代码中的运用
一讲计算机的发展,必定会提到二进制。虽然二进制对计算机的重要性经常被强调,但在利用高级语言(如:C#)的开发中,用得还是相对较少的。可这相对较少的运用,并不能成为我们不去理解他的借口。
一、二进制的运算。
(一)算术运算
从我们日常中熟悉的十进制来理解。从十进制的“0,1,2,3,4,5,6,7,8,9”减少到“0,1”。每位的容量从10到2的变化,仅此而已,就是这么简单。
1.加法:0+0=0,0+1=1 ,1+0=1, 1+1=10(向高位进位)
2.减法:0-0=0,0-1=1(向高位借位) 1-0=1,1-1=0
3.乘法:0*0=0,0*1=0,1*0=0,1*1=1
4.除法:0÷0=0,0÷1=0,1÷0=0 (和十进制相同,不能被0除,无意义),1÷1=1
说起这个,给大家讲个冷笑话。今天中午下楼时,电梯已经到1楼了,我却还愣在那儿。你们猜为什么?因为我还在等0楼。
这是一个程序员才能明白的笑话。
(二)逻辑运算
将1理解为布尔值true,将0理解为布尔值false。
1.加法:通常用符号“+”或“∨”来表示(或运算)
一个为真,结果即为真。
0+0=0, 0∨0=0
0+1=1, 0∨1=1
1+0=1, 1∨0=1
1+1=1, 1∨1=1
2.乘法:通常用符号“×”或“∧”或“·”来表示(与运算)
[Flags] public enum PFive { Russia = 1 << 0, China = 1 << 1, USA = 1 << 2, UK = 1 << 3, France = 1 << 4 }
这里,我们在用枚举项赋值时使用了按位左移运算。经过上面的介绍,我们很容易算出:
Russia = 1 << 0=1 (二进制1)
China = 1 << 1=2 (二进制10)
USA = 1 << 2=4 (二进制100)
UK = 1 << 3=8 (二进制1000)
France = 1 << 4=16 (二进制10000)
把1按二进制的位,一步一步往左移,是不是非常直观。
我们再来创建一个方法来判断常任理事国中,哪些国家是英语国家。
public static string CanSpeakEnglish(PFive p5) { if (((PFive.USA | PFive.UK) & p5) == p5) { return p5.ToString() + " is a English Country."; } else { return p5.ToString() + " is not a English Country."; } }
这里我们重点要提的是这一句代码:
((PFive.USA | PFive.UK) & p5) == p5
我们知道美国和英国是英语国家,那只要传入的国家是这两个国家中的一个,那它也就是英语国家了。
PFive.USA=4=100;
PFive.UK=8=1000;
PFive.USA | PFive.UK=100|1000=1100;
现在假设传入的国家是中国
PFive.China=2=10;
(PFive.USA | PFive.UK) &PFive.China=1100|0010=0000
0000!=PFive.China,返回false
现在假设传入的国家是英国
PFive.UK=8=1000;
(PFive.USA | PFive.UK) &PFive.UK=1100|1000=1000
1000==PFive.UK,返回true
所以通过按位运算,可以进行如上的一个简单判断。
这里需要提一下,为什么我们不能用普通的枚举值呢?很简单,如果Russia=1,China=2,USA=3,那么3可以代表USA,也可以代表Russia和China两个国家,这会造成一种混乱。