本文是對C#中的與,或,異或及移位運算進行了詳細的介紹榄攀,需要的朋友可以過來參考下,希望對大家有所幫助临谱。
1.剖析異或運算(^)
二元 ^ 運算符是為整型和 bool 類型預定義的宅静。對于整型,^ 將計算操作數(shù)的按位“異或”兜辞。對于 bool 操作數(shù)迎瞧,^ 將計算操作數(shù)的邏輯“異或”;也就是說弦疮,當且僅當只有一個操作數(shù)為 true 時夹攒,結(jié)果才為 true。
數(shù)值運算舉例
按位異或的3個特點:
(1) 00=0,01=1 0異或任何數(shù)=任何數(shù)
(2) 10=1,11=0 1異或任何數(shù)-任何數(shù)取反
(3) 11=0,00=0 任何數(shù)異或自己=把自己置0
例如:10100001^00010001=10110000
按位異或的幾個常見用途:
(1) 使某些特定的位翻轉(zhuǎn)
例如對數(shù)10100001的第2位和第3位翻轉(zhuǎn)胁塞,則可以將該數(shù)與00000110進行按位異或運算。
0100001^00000110 = 10100111
(2) 實現(xiàn)兩個值的交換压语,而不必使用臨時變量啸罢。
例如交換兩個整數(shù)a=10100001,b=00000110的值胎食,可通過下列語句實現(xiàn):
a = a^b扰才; //a=10100111
b = b^a; //b=10100001
a = a^b厕怜; //a=00000110
(3) 在匯編語言中經(jīng)常用于將變量置零:
xor a衩匣,a
(4) 快速判斷兩個值是否相等
舉例1: 判斷兩個整數(shù)a,b是否相等粥航,則可通過下列語句實現(xiàn):
return ((a ^ b) == 0)
舉例2: Linux中最初的ipv6_addr_equal()函數(shù)的實現(xiàn)如下:
static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
{
return (a1->s6_addr32[0] == a2->s6_addr32[0] &&
a1->s6_addr32[1] == a2->s6_addr32[1] &&
a1->s6_addr32[2] == a2->s6_addr32[2] &&
a1->s6_addr32[3] == a2->s6_addr32[3]);
}
可以利用按位異或?qū)崿F(xiàn)快速比較, 最新的實現(xiàn)已經(jīng)修改為:
static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
{
return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);
}
2 & 運算符(與)
1 & 0 為0
0 & 0 為0
1 & 1 為1
3 | 運算符(或)
1 & 0 為1
0 & 0 為0
1 & 1 為1
C#移位運算(左移和右移)
C#是用<<(左移) 和 >>(右移) 運算符是用來執(zhí)行移位運算琅捏。
左移 (<<)
將第一個操作數(shù)向左移動第二個操作數(shù)指定的位數(shù),空出的位置補0递雀。
左移相當于乘. 左移一位相當于乘2;左移兩位相當于乘4;左移三位相當于乘8柄延。
x<<1= x2
x<<2= x4
x<<3= x8
x<<4= x16
同理, 右移即相反:
右移 (>>)
將第一個操作數(shù)向右移動第二個操作數(shù)所指定的位數(shù),空出的位置補0缀程。
右移相當于整除. 右移一位相當于除以2;右移兩位相當于除以4;右移三位相當于除以8搜吧。
x>>1= x/2
x>>2= x/4
x>>3= x/8
x>>4=x/16
如
int i = 7;
int j = 2;
Console.WriteLine(i >> j); //輸出結(jié)果為1
當聲明重載C#移位運算符時,第一個操作數(shù)的類型必須總是包含運算符聲明的類或結(jié)構(gòu)杨凑,并且第二個操作數(shù)的類型必須總是 int,如:
class Program
{
static void Main(string[] args)
{
ShiftClass shift1 = new ShiftClass(5, 10);
ShiftClass shift2 = shift1 << 2;
ShiftClass shift3 = shift1 >> 2;
Console.WriteLine("{0} << 2 結(jié)果是:{1}", shift1.valA, shift2.valA);
Console.WriteLine("{0} << 2 結(jié)果是:{1}", shift1.valB,shift2.valB);
Console.WriteLine("{0} >> 2 結(jié)果是:{1}", shift1.valA, shift3.valA);
Console.WriteLine("{0} >> 2 結(jié)果是:{1}", shift1.valB, shift3.valB);
Console.ReadLine();
}
public class ShiftClass
{
public int valA;
public int valB;
public ShiftClass(int valA, int valB)
{
this.valA = valA;
this.valB = valB;
}
public static ShiftClass operator <<(ShiftClass shift, int count)
{
int a = shift.valA << count;
int b = shift.valB << count;
return new ShiftClass(a, b);
}
public static ShiftClass operator >>(ShiftClass shift, int count)
{
int a = shift.valA >> count;
int b = shift.valB >> count;
return new ShiftClass(a, b);
}
}
}
因為位移比乘除速度快.對效率要求高,而且滿足2的冪次方的乘除運方,可以采用位移的方式進行滤奈。