0基礎學演算法 第七彈 位運算
- 2020 年 6 月 12 日
- 筆記
今天要講的內容主要分為兩個大塊,一個呢就是位運算,另一個呢就是關於二進位的原碼反碼補碼,位運算的應用也算是比較多的了,進行位運算有時候可以省略不少事情呢,當然,也不是說不會位運算就會天崩地裂,畢竟事實上,在學位運算之前,我都是用其他方法來強制性模擬位運算(當時我並不知道什麼是位運算)不過多學一些也是好的,省事兒,而且更快
呃,講正事之前打個小廣告,歡迎大家進QQ群1031457671,名字叫c++演算法學習交流群,大家可以來交流學習(群里有很多資料呢 ps:本來之前想直接傳到blog的)
一,二進位的原碼反碼和補碼
相信二進位沒有人不熟悉的,逢二進一,一個二進位數由0和1組成,他的最高位就是他的正負符號,0是正數,1是負數,例如10001000,這就是一個負的二進位數,當然最高位是0就是正數
原碼之所以叫做原碼,必然是因為它就像是萬物之源,補碼、反碼都是在他的基礎上變化的,當最高位是0的時候,也就是正數的時候,原碼==反碼==補碼
以下關於反碼及補碼的概念是基於最高位是1的情況(負數的情況)
反碼,顧名思義,是原碼顛倒過來的樣子,除了最高位表示負號的那個「1」不變以外,其他的數位上的數 全部取反,1變0,0變1,假設原碼為1001010100,它的反碼就是1110101011,再假設原碼是0111001,它的反碼就是0111001,是不是有點奇怪,哈,我前面說過了,當原碼是正數的時候,原碼==反碼==補碼
補碼,在原碼是正數的情況下是等於原碼或者反碼的,但是在負數情況下,他恰好是反碼加1,比如原碼是100000,反碼就是111111,補碼就是1000000
二,進入正題,位運算
在系統的講位運算之前,先給大家一張圖表,方便大家查詢
註明:位運算符號在c++中用法同算數運算符
首先是&
其實位運算不複雜,理解了就好,比如說&,把他理解成1代表true,2代表false,1&&2,明顯為false(2),2&&2明顯也為false(2),只有1&&1的時候才為true(1);
但是這是if語句裡面的判斷方法,而『&』的運算方法是這樣的,比如1010&0011,運算過程如下圖
至於|的話。。。就是上下兩個數只要有一個為1,結果就為1啦,如1100|0011=1111
『~』!也比較好理解,做它的運算的時候,只需要傳一個二進位數,針對每一位進行運算可以從在每一位上如~1001=0110;
^,亦或,算起來也比較簡單,只要兩位不相等,結果就為1,舉例,1001^0101=1100
最後一組”<<“和」>>”這個是左移和右移的操作
請看
int類型的二進位是32位的,而long long是64位,左移和右移
例如,給出一個標準的32的int類型00000000000000000000000000000001,當我們使用左移的時候,整體忘左移,並在後面補零
有一道題,可以通過位運算做的很簡便,但如果你不會位運算的話。。。就另當別論了
如果你不用位運算,你要寫很複雜的程式碼,但是用了,你就只要10行程式碼,如假包換(雖然我絕對不換)
題目鏈接→//www.luogu.com.cn/problem/P1100
看到題目,很清晰了,首先錄入兩個字元串,然後將它轉成二進位,接著把前16位和後16位的數交換位置,最後結果轉成十進位輸出!好,完美。。。
停!
今天利用我們學的位運算壓根不用這麼麻煩!
直接用上我們的左移”<<“和右移”>>”啊!
只要左移後16位,右移前16位不就好了?
廢話不多說,大家請看最短程式碼!
#include<bits/stdc++.h> using namespace std; unsigned int x; int main(){ cin>>x;//錄入x cout<<((x<<16)|(x>>16));//將左移16位後的x和右移16位的x用或"|"將他們重新連起來 return 0;//完美 }
完美撒花🎉🎉🎉🎉🎉🎉🎉
如果覺得我講的不錯的,麻煩點個關注➕,點個贊👍,以後還會更新的😀
ps:再次歡迎大家進QQ群1031457671,我會持續在裡面投放我有的資料👽!