前言
(題目我大概是隨便編的,感覺叫這個比較能概括我總結的主題)
在學OI的過程中,我一開始完全不懂位運算,後來經過一些題目的記憶,也是能夠記下來算術運算子它們的效果和作用,但是總是忘記每個運算子具體的效果,比如或運算與運算之類。
今天無意間翻開物理書,看到邏輯電路那一節,裡面的與,或不就是算術位運算的效果嗎?我突然感到自己是個弱智,先前都是在死記硬背(數學課講邏輯的時候也有與和或,當時沒有聯想到按位運算,只是想到了對於條件且(&&)和條件(||)的類比)
(我死記硬背的方法——在便箋裡放著小口訣)
於是我打算改變我憨批一般的死記硬背,從更基本的邏輯電路出發來記憶和理解各個位運算的效果。
將數學語言上的邏輯,計算機上的邏輯(程式語言),電路上的邏輯(其實也是計算機底層的邏輯吧)統一起來,讓自己更清晰。
而眾所周知,計算機位運算中有 “與” “或”“非”“異或”四種算術位運算,下面將分別分析和統一它們。
##事先備註,下文的表述中在數學上只是邏輯語言,用於一種描述或進行推論;而表現在計算機中,這些邏輯運用都是二進位制下按位運算,也就是對二進位制數的每一位都進行這樣的邏輯運算;物理上就是邏輯閘的關係,(當然還存在“與非”“或非”等等,本文只講述與c++位運算有關內容,這些並無直接對應,但可以通過組合實現)。它們只是在邏輯上統一,具有相同的邏輯關係,並非含義等同。
基本介紹
-
與 :
符號:
數學: ∧ (這個不是^(次方或者異或符號),是邏輯與)
計算機(c++)(其實是按位與) : and & (整條語句為“&&”)
具體描述 :
都為真才為真 ,或者說 輸入都為1(true) 才輸出 1(true) ,再或者說 條件都為1(true) 結論才為1(true)。
對於c++來說,使用第二條來記錄比較具象(就是我便箋上寫的)。
物理上的邏輯(開關串聯):
我們規定開關關閉(斷路)則表示條件(邏輯再者說輸入)為0(假),開關開啟(通路)則表示條件(邏輯再者說輸入)為1(真),
兩者都為1的時候,兩者都為0(0&0),燈泡的狀態為不亮,即表現為0(假);同時,開關一開一關(0&1),
顯然燈泡也不會亮,即表現為0(假);只有二者均為1(1&1)的時候,燈泡才會亮,即表現為1(真);
運算表示式:
數學(其實數學這裡“與”其實是“邏輯且(邏輯與)”吧,對應在程式裡是&&而不是按位與的&,但它們在邏輯上是並通的):
如果條件p為假,條件q為假,那麼 p∧q=假;
如果條件 p為真,q為假或者p為假,q為真 ,那麼p∧q=假;
如果p,q都為真,那麼p∧q=真
抽象點(有定義,乘法為與,"+"表邏輯或,條件加“ ' ”為非):
F=AB (AB都為1,F才為1)
計算機(二進位制按位運算):
0&0=0;1&0=0;0&1=0;1&1=1;
物理:這咋表達?這個只能用圖
邏輯上的統一就是:都為真才得到真(這不還是那句話?——但是我們多了個物理含義!是不是更好記了?)
-
或:
符號:
數學: ∨
計算機(c++): or | (對於整條語句來說是“||”)
具體描述:
只要有一個為真就是真,都為假時才是假;或者說輸入有一個為1(true)就是1(true),都為0(false)才是假;
再或者說,條件有一個為1(true)結論就為1(true),條件均為0(false)結論才為0(false)。
對於c++來說,仍然是第二條。
物理上的邏輯(開關並聯):
同樣的,開關通路(開)則表示1,斷路(關)則表示0。如圖
兩者都為1(開)的時候(1|1),則為1,任意一者為1(1|0)的時候也為1,即這兩種情況燈是亮的;
而只有兩者都為0(0|0)的時候才為0,即燈是不亮的;
運算表示式:
數學(同邏輯與,數學的含義實際類似於“||”):
如果條件p,q至少有一個為真,則p∨q=真。
如果條件都為假,則p∨q=假。
抽象點(有定義,乘法為與,"+"表邏輯或,條件加“ ' ”為非):
F=A+B (AB只要有一個為1,F就不為0)
計算機(二進位制按位運算):
1|1=1;0|1=1;1|0=1;0|0=0;
物理:並聯開關一個為開則幹路上的燈為亮,都關了才不亮。
邏輯上的統一就是:都為假才是假
-
非:
符號:
數學: ¬
計算機(c++): ~ (對於整條語句來說是“!”,不過在c++的條件語句裡,二者都可以作用於一個判斷語句的真假,但對數字按位取反要用~)
具體描述:
是真則為假,是假則為真。輸入為輸出相反。條件與結論相反。
c++同樣為第二條。
物理上的邏輯(開關串聯,與燈泡並聯):
同上,很顯然的就是,開關開啟(通路)時燈泡不亮(被短路了) (!1),即為0,開關關閉(斷路)時燈泡亮(!0),即為1。
運算表示式:
數學: 若p為真,則¬p為假
若p為假,則¬p為真
抽象點(有定義,乘法為與,"+"表邏輯或,條件加“ ' ”為非):
F=A'
計算機(二進位制按位運算): 這個比較特殊,因為如果要按位非的話,也就是按位取反
由於計算機內一個數字變數型別的最高為(比如int的第32位)符號位,按位取反則對從32到1所有取反
所以說~1=-2,~0=-1。但是
!0=1 !1=0
實際上除了!0之外的所有數進行!操作,都是0
"!"只是逆轉真假罷了,一個數只有是0的時候才是假,所以只有0的時候進行"!"才是真,於是造成了這樣的結果。
物理:開開關燈就滅,關開關等就亮
統一的邏輯就是:是真則為假,是假則為真
-
異或:
符號:
數學: ⊕
計算機(c++): xor ^
具體描述:
相同則為假,相異則為真。輸入都為0或1則為假,輸入為一0一1則為真。條件都真或者都假結論就假,條件一真一假才為真。
c++同樣為第二條。
物理上的邏輯(不好用語言描述圖了,口胡一下:非電路和另一開關構造與電路,再交換開關複製成或電路):
圖一(嚴格按照數學表示式):
,
令上下的並聯開關為k1,可以理解為同一個開關,二者操作同時,表達同時同等,k2理解為另一個開關,二者同時同等。
當k1開啟,k2關閉的時候(1^0),上路的燈可以亮,當k2開啟,k1關閉的時候(0^1),下路的燈可以亮。
當k1,k2都關閉(0^0)或者都開啟(1^1)的時候,兩個路的燈都不可以亮。
總的表示就是開關狀態相同則不亮,開關狀態不同則亮。
圖2(與非電路串或電路,並藉此分析異或的條件與結論的關係):
如圖。還是兩個k1同步,兩個k2同步。(下面的敘述較長,於是我以插入程式碼的形式壓縮了起來)
左邊這團電路是"與非電路",與非電路即先與再非的電路,當"與"表達為假的時候總表達為真,反之為假。 右邊的或電路和燈是串的,所以邏輯就是單純的或。 如果只有左電路,開關都開啟燈一定不亮,燈不亮時開關一定都開啟(開關是通路,燈被短路),二者互為充要條件。 放在整個電路中,雖然燈不亮時開關不一定都開啟,但開關都開啟時燈一定不亮(被短路), 所以開關都開啟是燈不亮的充分不必要條件,燈不亮是開關都開啟的必要不充分條件。 如果只有右電路,開關都關閉燈一定不亮,燈不亮時開關一定都關閉(燈被斷路),二者互為充要條件。 放在整個電路中,雖然燈不亮時開關不一定都關閉,但開關都關閉時燈一定不亮, 所以開關都關閉時燈不亮的充分不必要條件,燈不亮是開關都關閉的必要不充分條件。 以上分析可知,開關都開或者都閉的時候(0^0或者1^1),燈一定不亮(0)。燈不亮的時候一定是開關都開或都關的時候。 也就是說,開關狀態一致和燈的不亮,互為充要條件,既然它們互為充要,如果畫成韋恩圖,二者等價。 到這裡可以用數學的邏輯推出來開關不一致對應的是燈亮: 很明顯開關狀態不一致是和開關狀態一致是相反的說法,沒有交集,所以說它對開關的不亮是既不充分也不必要條件。 因為開關如果分成一致(0)或不一致(1)只有0/1兩個狀態,燈泡的亮與不亮也只有兩個狀態,所以說燈亮的時候一定和開關狀態不一致時等價的。 也就是說開關狀態不一致的時候,燈一定是亮的。 具體來說,開關狀態不一致的時候,"與非電路"為真(1),而或電路也為真(1),二者又是與的關係,都為真(1) 則表達為真(1),所以說燈泡就是亮的,為真(1)。
其實個人覺得兩個圖都比較好記,圖一的優點在於完全對應數學表達,圖二的優點在於不在乎k1,k2的交換,只要左右電路分別有對k1,k2就行。
運算表示式:
數學:條件p和條件q一真一假,則 p ⊕ q=真
條件p和條件q都為真或者都為假,則p ⊕ q =假
抽象點(有定義,乘法為與,"+"表邏輯或,條件加“ ' ”為非):
F=AB'+A'B(完全對應圖1,圖二相當於 F=(AB)'(A+B),兩式結果相同)
計算機(c++):
0^0=0;1^1=0;0^1=1;1^0=1;
統一的邏輯就是:同則為0,異則為1。
後記
寫下來花了兩三個小時,儘管已經查閱資料儘量保證語言的嚴謹性,但總怕難免有我誤解的地方。
不過大的錯誤應該沒有,或許會有小地方術語說錯的,不過不影響物理圖數學公式和c++邏輯上的統一性。
寫完之後感覺自己受益良多,強化加深了自己在邏輯運算和位運算方面的理解,甚至包括一些c++語法上的理解。
同時我再也不會忘了這些算術運算子在c++的效果了。
到此結束!
希望看到的人也能有收穫,同時歡迎各位提出建議,批評指正。