二進制運算理解及在代碼中的運用


一講計算機的發展,必定會提到二進制。雖然二進制對計算機的重要性經常被強調,但在利用高級語言(如: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兩個國家,這會造成一種混亂。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM