2020-11-20 邏輯運算(異或為什么可以交換值)

前言

在寫冒泡排序的時候,同事看了我的代碼供搀,跟我說隅居,你這個數(shù)據(jù)交換,不需要中轉(zhuǎn)站的葛虐,用一個異或操作就可以啦胎源。具體代碼是:

a = 2;
b = 3;
// 數(shù)據(jù)交換(未使用異或)
temp = a;
a = b;
b = temp;
// 數(shù)據(jù)交換(使用異或)
a = a ^ b;
b = a ^ b;
a = a ^ b;
// a = 3, b = 2;

怎么樣,乍一看是不是有點驚奇屿脐,別著急涕蚤,讓我們一探究竟。

邏輯門

  • 與門:全為1才出1
  • 或門:有1就出1
  • 非門:全為0才出1
  • 同或門:相同就出1
  • 異或門:不同就出1
  • 與非門:先與再非(全為1就出0)
  • 或非門:先或再非(有1就出0)

這八種邏輯門在數(shù)字電路中非常重要的诵,但是我們程序員只需要了解即可万栅。

邏輯運算

  • 邏輯與(&&):
    運算符左側(cè)為真值則繼續(xù)往后運算,運算符左側(cè)為假值西疤,則返回運算符左側(cè)值申钩。
    1 && 2 && 3 // 3
    1 && 0 && 2 // 0
    0 && 2  // 0
    
  • 與運算(&):
    將運算符左右值轉(zhuǎn)化為二進制數(shù)進行邏輯門運算,true轉(zhuǎn)為1瘪阁,false轉(zhuǎn)為0撒遣,true與奇數(shù)得1邮偎,false與任何數(shù)都得0
    3 & 2 // 3
    true & 1 // 1
    true & 2 // 0
    
  • 邏輯或(||):
    向右查找到第一個真值,并返回义黎。
    0 || 3 || 4 // 3
    1 || 2 || 3 // 1
    
  • 或運算(|):
    和與運算相同禾进,先轉(zhuǎn)化為二進制再進行邏輯門運算。
    0 | 1 // 1
    3 | 4 // 7
    
  • 非運算(!):
    非運算就是取值的“反”廉涕,真的變成假的泻云,假的變成真的,只輸出true/false狐蜕,可疊加運算
    !1 // false
    !0 // true
    !!!1 // false
    
  • 異或運算(^):
    將值轉(zhuǎn)化為二進制宠纯,進行異或門運算
    2 ^ 3 // 1
    1 ^ 3 // 2
    1 ^ 2 // 3
    
    發(fā)現(xiàn)規(guī)律了嗎?通過異或层释,我們可以利用值本身婆瓜,將兩個值進行交換。
為什么是異或

二進制數(shù)只有兩個值贡羔,不是0就是1廉白,那么重點來了:
兩個數(shù)不同就表明他們二進制表示中有一位或者多位不同,如10和12:

10的二進制:1010
12的二進制:1100

一對比乖寒,發(fā)現(xiàn)這兩個數(shù)的中間兩位數(shù)是不同的猴蹂。那異或運算特點是什么?不同就出1楣嘁。那說明兩個數(shù)進行異或以后磅轻,他們不同的位置的數(shù)就會變成1。

10 ^ 12 // 0110

很明顯逐虚,中間兩位是1聋溜,代表10和12的二進制表示,中間兩位數(shù)是不同的痊班。與上面我們推斷出的規(guī)律是一樣的勤婚。

交換位置

兩個不同的數(shù)想要交換,而我們已經(jīng)知道了兩個數(shù)的二進制表示中涤伐,哪些位的值是不同的馒胆,所以只需要將不同位的數(shù)交換即可。

第一次異或
a = 10; // 1010
b = 12;  // 1100
// 第一次
a = a ^ b;  // 0110

此時a的值為0110凝果,b還是原來的值12(1100)祝迂。a是代表了原來a和b的差異值(中間兩位不同);

第二次異或
b = a(差異值) ^ b(初始b);  // 1010

此時b的值是差異值a和原來b值異或的結(jié)果器净。

注意觀察型雳,異或是找不同,可以得出:
已知左邊一位數(shù)為0,那右邊對應(yīng)位置的數(shù)一定是其本身(0代表相同纠俭,出0沿量,1代表不同,出1)
已知左邊一位數(shù)為1冤荆,那右邊對應(yīng)位置的數(shù)一定取反(0代表不同朴则,出1,1代表相同钓简,出0)

那說明此時b是原來的b值將二進制表示的中間兩位進行取反的結(jié)果乌妒。還記得第一次異或得出了什么結(jié)論嗎?a與b再二進制表示中 中間兩位 不同外邓,
既然b已經(jīng)進行了差異位的取反撤蚊,那不就變成了原來a的值了嗎?--仔細想想

第三次異或
a = a(差異值) ^ b(初始a);  // 1010將中間兩位取反损话,得出1100

第二次異或結(jié)束后侦啸,差異值0110,中間兩位為1席镀,邊上兩位為0匹中,利用上面的結(jié)論夏漱,在第三次異或中豪诲,得出a的值為b(原來的a)進行差異取反,也就得到了原來的b的值挂绰。

結(jié)論

異或交換的核心思想就是:

  • 第一次異或得到差異值屎篱,將其隨意賦給一個值a;
  • 第二次異或通過差異取反(差異值a ^ b)可以得到a的原始值,將其賦給b葵蒂;
  • 第三次異或還是通過差異取反(差異值a ^ b(原始值a))得到原始值b交播,將其賦給a;

廢話

不由感嘆數(shù)學果然讓人頭禿,誓要成為數(shù)學亡子 [滑稽]践付。

周五就該下棋秦士,九五至尊不香嗎?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末永高,一起剝皮案震驚了整個濱河市隧土,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌命爬,老刑警劉巖曹傀,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異饲宛,居然都是意外死亡皆愉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幕庐,“玉大人久锥,你說我怎么就攤上這事∫彀” “怎么了奴拦?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長届吁。 經(jīng)常有香客問我错妖,道長,這世上最難降的妖魔是什么疚沐? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任暂氯,我火速辦了婚禮,結(jié)果婚禮上亮蛔,老公的妹妹穿的比我還像新娘痴施。我一直安慰自己,他們只是感情好究流,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布辣吃。 她就那樣靜靜地躺著,像睡著了一般芬探。 火紅的嫁衣襯著肌膚如雪神得。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天偷仿,我揣著相機與錄音哩簿,去河邊找鬼。 笑死酝静,一個胖子當著我的面吹牛节榜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播别智,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宗苍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了薄榛?” 一聲冷哼從身側(cè)響起讳窟,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蛇数,沒想到半個月后挪钓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡耳舅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年碌上,在試婚紗的時候發(fā)現(xiàn)自己被綠了倚评。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡馏予,死狀恐怖天梧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情霞丧,我是刑警寧澤呢岗,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站蛹尝,受9級特大地震影響后豫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜突那,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一挫酿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧愕难,春花似錦早龟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至猜丹,卻和暖如春芝加,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背居触。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工妖混, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留老赤,地道東北人轮洋。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像抬旺,于是被迫代替她去往敵國和親弊予。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容