• 二进制运算理解及在代码中的运用


    一讲计算机的发展,必定会提到二进制。虽然二进制对计算机的重要性经常被强调,但在利用高级语言(如: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.乘法:通常用符号“×”或“∧”或“·”来表示(与运算)

    都为真时,结果才为真。
    0×0=0, 0∧0=0, 0·0=0
    0×1=0, 0∧1=0, 0·1=0
    1×0=0, 1∧0=0, 1·0=0
    1×1=1, 1∧1=1, 1·1=1
     
    3.否定:(非运算)
    原本为真,结果为假,原来为假,结果为真。
    0=1 非0即1
    1=0 非1即0
     
    4.异或:通常用符号"⊕"表示(半加运算)
    只有一个为真,一个为假时,结果才为真。
    0⊕0=0 0同0异或,结果为0
    0⊕1=1 0同1异或,结果为1
    1⊕0=1 1同0异或,结果为1
    1⊕1=0 1同1异或,结果为0
     
    (三)位运算
    理解逻辑运算后,再来看位运算就容易多了。简单地说,位运算就是对二进制的对应位进行逻辑运算。
    以十进制5转换为二进制为101,十进制19转换为二进制为10011为例。
     
    1.按位或:通常用符号"|"或"or"表示
    101|10011=00101|10011
    各位对应按逻辑或运算,有一方为1即为1。
    最后结果为:10111。
     
    2.按位与:通常用符号"&"或"and"表示
    00101&10011
    各位按逻辑与运算,两方为1结果才为1
    最后结果为:1
     
    3.按位异或:通常用符号"^"或"xor"表示
    00101^10011
    各位按逻辑异或运算,一方为0另一方为1结果才为1
    最后结果为:10110
     
    4.按位取反:通常用符号"~"或"not"表示
    将本身各位,0换为1,1换为0。
    以一个字节(八位)为例:
    ~0000 0101=1111 1010
    ~0001 0011=1110 1100
     
    5.按位左移:通常用符号"<<"或"shl"表示
    将本身各位向左移动相应位数。
    0000 0101<<1=0000 1010
    0001 0011<<1=0010 0110
     
    6.按位右移:通常用符号">>"或"shr"表示
    0000 0101>>1=0000 0010
    0001 0011>>1=0000 1001
     
    二、应用实例
    我们以贴有Flags标签的枚举值举例说明,二进制的一点用法。
    首先,创建一个枚举类。
        [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两个国家,这会造成一种混乱。
  • 相关阅读:
    c# 集合运算
    Nuxt
    引入js,不共享变量
    sourcetree将存在的本地项目提交到远程仓库
    c#DateTime与unix时间戳互相转换
    IfcBoundingBox
    IfcBooleanResult
    IfcAnnotationFillArea
    IfcGeometricRepresentationItem
    IfcRepresentationItem
  • 原文地址:https://www.cnblogs.com/Figgy/p/4743865.html
Copyright © 2020-2023  润新知