2017年10月19日 星期四

exclusive or :XOR


A ⊕ 1 = A'; //某些特定位元反轉
A ⊕ 0 = A;
A ⊕ A = 0; //快速比較兩個值;將變數reset
A ⊕ A' = 1;

➠ 將變數設為零  a^=a
快速比較兩個值  if ((a^b) == 0) {}

include/linux/etherdevice.h
/**
 * ether_addr_equal - Compare two Ethernet addresses
 * @addr1: Pointer to a six-byte array containing the Ethernet address
 * @addr2: Pointer other six-byte array containing the Ethernet address
 *
 * Compare two Ethernet addresses, returns true if equal
 *
 * Please note: addr1 & addr2 must both be aligned to u16.
 */
static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
    u32 fold = ((*(const u32 *)addr1) ^ (*(const u32 *)addr2)) |
           ((*(const u16 *)(addr1 + 4)) ^ (*(const u16 *)(addr2 + 4)));

    return fold == 0;

#else
    const u16 *a = (const u16 *)addr1;
    const u16 *b = (const u16 *)addr2;

    return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0;

#endif
}

➠ 某些特定位元反轉
status ^= 1 << x;                             //Toggling a bit
status |= 1 << x; //Setting a bit
status &= ~(1 << x);                         //Clearing a bit
bit = (status >> x) & 1;                     //Checking a bit
status ^= (-x ^ status) & (1 << n);     //Changing the nth bit to x
unsigned int a, b, mask = 1 << 6; 
a = 0xB1; // 10100001 
b = a ^ mask; /* flip the 6th bit */
https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit

一個二進制數中1的數量是奇數還是偶數 (Parity Check)
例如:求10100001中1的數量是奇還是偶數; 
答案:1 ^ 0 ^ 1 ^ 0 ^ 0 ^ 0 ^ 0 ^ 1 = 1,
結果為1就是奇數個1,結果為0就是偶數個1;

校驗和恢復
if (a ^ b = c) then a ^ c = b
RAID5: 使用三塊磁盤(A、B、C)組成RAID5陣列,當寫資料時,將資料分成兩部分,分別寫到磁盤A和磁盤B,A^B的結果寫到磁盤C,
當讀取A的資料時,透過B ^ C可以對A的數據做校驗
當磁盤A出錯時,透過B ^ C也可以恢復磁盤A的資料

➠ [面試] XOR swap  #define swap(a,b) { a^=b, b^=a, a^=b; }
不用宣告新變數直接做swap
x = a ^ b
y = x ^ b
z = x ^ y

y = (a ^ b) ^ b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a
z = (a ^ b) ^ a = a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
https://en.wikipedia.org/wiki/XOR_swap_algorithm

➠ [面試] 互換二進制數的奇偶位
#define N(n) ((n<<1) & 0xAAAAAAAA) | ((n>>1) & 0x55555555)
將一個int型態的數的奇偶位互換
例如6的2進制為00000110,交換後得到00001001,輸出應該為9

➠ OddOccurrencesInArray
一個數組存放若干整數,一個數出現奇數次,其餘數均出現偶數次,找出這個出現奇數次的數?
交換律:A ^ B = B ^ A 
結合律:A ^ (B ^ C) = (A ^ B) ^ C

A ^ B ^ C ^ B ^ C ^ D ^ A

= A ^ A ^ B ^ B ^ C ^ C ^ D
= 0 ^ 0 ^ 0 ^ D
= 0 ^ D
= D
int iterator;
int result;
for (result = A[0], iterator = 1; iterator < N; result ^= A[iterator], iterator++);
return (result);
https://github.com/avrahamcohen/CodilitySolutions/blob/master/OddOccurrencesInArray.c

題目: 一個整數類型組除了一個數字之外,其他的數字都出現了兩次,找出這一個數字
題目: 一個整數類型組除了二個數字之外,其他的數字都出現了兩次,找出這二個數字
題目: 一個整數類型組除了三個數字之外,其他的數字都出現了兩次,找出這三個數字
https://www.lijinma.com/blog/2014/05/29/amazing-xor/

➠ 1 ~ 1000放在含有1001個元素的數組中,只有唯一的一個元素值重複,其它均只出現一次
每個數組元素只能訪問一次,不用輔助儲存空間
http://www.atove.com/Article/Details/635F056EDD0150910AEC759527EFD539

沒有留言:

張貼留言