1. 程式人生 > >轉載 -- 按位異或的性質及其妙用

轉載 -- 按位異或的性質及其妙用

https://www.jianshu.com/p/86a7cf855e51

 

文章摘要:
1、按位異或,可以簡單理解成:不進位加法。即:1+1=0;0+0=0;1+0 =1;
2、任何數和自己異或結果為零。
3、按位異或自反性。兩次運算操作,可以將最後的結果還原。
4、任何數和0做異或值不變,和1異或結果為原運算元取反。
5、交換律。不使用中間變數,交換兩個數。


一、按位異或具有自反性。即:對同一個資料,進行兩次按位異或操作,等於資料本身。


int displayOptions = 0x1100;
int flag = 0x1001;
int result = displayOptions ^ flag;

System.out.println(Integer.toHexString(displayOptions) 
                + " ^ " + Integer.toHexString(flag)
                + " = " + Integer.toHexString(result));
//第一次運算:1100 ^ 1001 = 0101

result = result ^ flag;
System.out.println(Integer.toHexString(displayOptions) 
                + " ^ " + Integer.toHexString(flag)
                + " = " + Integer.toHexString(result));
// 第二次運算:0101 ^ 1001 = 1100(displayOptions)

//我們還可以直接使用如下的程式碼直接進行測試:
System.out.println(Integer.toHexString(displayOptions ^ flag ^ flag));

二、應用案例

場景:
大房子中有很多關閉的電燈,隨機操作電燈開關,實時顯示房間中電燈的狀態,並允許一鍵關閉所有電燈。【只允許使用按位異或】

分析:
1、連續兩次操作電燈開關,電燈將處於操作前狀態。
2、關閉所有開關。任何數和自己異或結果為零。

實現:
1、定義“大房子”類。
lightFlags 標識房間全部電燈實時狀態。
封裝電燈操作方法以及一鍵關閉所有電燈的方法。

/**
 * 1、按位運算操作應用。
 * 2、走廊燈、廁所燈、廚房燈、主臥燈、次臥燈分別對應一個欄位位
 * 走廊燈=0000 0001
 * 廁所燈=0000 0010
 * 廚房燈=0000 0100
 * 主臥燈=0000 1000
 * 次臥燈=0001 0000
 * @author DrodYoung
 */
static class 大房子{
 private static final int 走廊燈 = (1 << 0); // 1{0000 0001}
 private static final int 廁所燈 = (1 << 1); // 2{0000 0001}
 private static final int 廚房燈 = (1 << 2); // 4{0000 0001}
 private static final int 主臥燈 = (1 << 3); // 8{0000 0001}
 private static final int 次臥燈 = (1 << 4); //16{0000 0001}
 
 private static final int LIGHT_MASK = 走廊燈|
     廁所燈|
     廚房燈|
     主臥燈|
     次臥燈;
 //lightFlags = 電燈狀態標記欄位。
 private int lightFlags = 0;
 
 private void 操作電燈開關(int flag){
   lightFlags ^= flag;
 }
 //任何數和自己異或結果為零。
 private void 讓所有的燈關閉(){
 操作電燈開關(lightFlags);
 }

 @Override
 public String toString() {
 return "房子中電燈狀況:\n"
 +"走廊燈="+(((lightFlags&走廊燈)!=0)?"開":"關")+"\n"
 +"廁所燈="+(((lightFlags&廁所燈)!=0)?"開":"關")+"\n"
 +"廚房燈="+(((lightFlags&廚房燈)!=0)?"開":"關")+"\n"
 +"主臥燈="+(((lightFlags&主臥燈)!=0)?"開":"關")+"\n"
 +"次臥燈="+(((lightFlags&次臥燈)!=0)?"開":"關")+"\n";
 }
 
}

2、測試:

//1、初始化大房子物件
大房子 hourse = new 大房子();
System.out.println(hourse);

//2、操作廚房燈開關
hourse.操作電燈開關(大房子.廚房燈);
System.out.println(hourse);//廚房燈為【開】

//3、再次操作廚房燈開關
hourse.操作電燈開關(大房子.廚房燈);
System.out.println(hourse);//廚房燈為【關】

//4、依次操作主臥燈、次臥燈、走廊燈開關
hourse.操作電燈開關(大房子.主臥燈);
hourse.操作電燈開關(大房子.次臥燈);
hourse.操作電燈開關(大房子.走廊燈);
//5、一鍵關閉所有燈
hourse.讓所有的燈關閉();
System.out.println(hourse);

三、總結:

妙用按位異或,可以讓程式碼更加簡潔、高效。本例演示了按位異或的自反性,異或還有其他妙用,我們可以總結如下:

  • 1、按位異或,可以簡單理解成:不進位加法。即:1+1=0;0+0=0;1+0 =1;
  • 2、任何數和自己異或結果為零。
  • 3、任何數和0做異或值不變,和1異或結果為原運算元取反。
  • 4、交換律。不使用中間變數,交換兩個數。
a=a^b;  
b=a^b;  
a=a^b; 



作者:Android那些事兒
連結:https://www.jianshu.com/p/86a7cf855e51
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。