1. 程式人生 > >0基礎學演算法 第七彈 位運算

0基礎學演算法 第七彈 位運算

  今天要講的內容主要分為兩個大塊,一個呢就是位運算,另一個呢就是關於二進位制的原碼反碼補碼,位運算的應用也算是比較多的了,進行位運算有時候可以省略不少事情呢,當然,也不是說不會位運算就會天崩地裂,畢竟事實上,在學位運算之前,我都是用其他方法來強制性模擬位運算(當時我並不知道什麼是位運算)不過多學一些也是好的,省事兒,而且更快

  一,二進位制的原碼反碼和補碼

  相信二進位制沒有人不熟悉的,逢二進一,一個二進位制數由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,當我們使用左移的時候,整體忘左移,並在後面補零

右移也相似,只不過是低位被擠掉了,高位補0

 

 

  有一道題,可以通過位運算做的很簡便,但如果你不會位運算的話。。。就另當別論了

  如果你不用位運算,你要寫很複雜的程式碼,但是用了,你就只要10行程式碼,如假包換(雖然我絕對不換)

  題目連結→https://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;//完美
}

  完美撒花