C#运算符之与,或,异或及移位运算

1.剖析异或运算(^)

二元 ^ 运算符是为整型和 bool 类型预定义的。对于整型,^ 将计算操作数的按位“异或”。对于 bool 操作数,^ 将计算操作数的逻辑“异或”;也就是说,当且仅当只有一个操作数为 true 时,结果才为 true。

数值运算举例

按位异或的3个特点:
(1) 0^0=0,0^1=1  0异或任何数=任何数
(2) 1^0=1,1^1=0  1异或任何数-任何数取反
(3) 1^1=0,0^0=0  任何数异或自己=把自己置0

例如:10100001^00010001=10110000

按位异或的几个常见用途:
(1) 使某些特定的位翻转
    例如对数10100001的第2位和第3位翻转,则可以将该数与00000110进行按位异或运算。
       10100001^00000110 = 10100111

(2) 实现两个值的交换,而不必使用临时变量。
    例如交换两个整数a=10100001,b=00000110的值,可通过下列语句实现:
    a = a^b;   //a=10100111
    b = b^a;   //b=10100001
    a = a^b;   //a=00000110

(3) 在汇编语言中经常用于将变量置零:
    xor   a,a

(4) 快速判断两个值是否相等
    举例1: 判断两个整数a,b是否相等,则可通过下列语句实现:
        return ((a ^ b) == 0)
    
    举例2: Linux中最初的ipv6_addr_equal()函数的实现如下:
    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]);
    }
    
    可以利用按位异或实现快速比较, 最新的实现已经修改为:
    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#是用<<(左移) 和 >>(右移) 运算符是用来执行移位运算。

左移 (<<)

将第一个操作数向左移动第二个操作数指定的位数,空出的位置补0。
  左移相当于乘. 左移一位相当于乘2;左移两位相当于乘4;左移三位相当于乘8。

x<<1= x*2 
  x<<2= x*4 
  x<<3= x*8 
  x<<4= x*16

同理, 右移即相反:

右移 (>>) 
  将第一个操作数向右移动第二个操作数所指定的位数,空出的位置补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);   //输出结果为1

当声明重载C#移位运算符时,第一个操作数的类型必须总是包含运算符声明的类或结构,并且第二个操作数的类型必须总是 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 结果是:{1}", shift1.valA,  shift2.valA);            
  Console.WriteLine("{0} << 2 结果是:{1}", shift1.valB,shift2.valB);            
  Console.WriteLine("{0} >> 2 结果是:{1}", shift1.valA,  shift3.valA);            
  Console.WriteLine("{0} >> 2 结果是:{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的幂次方的乘除运方,可以采用位移的方式进行。

时间: 2024-08-11 05:36:38

C#运算符之与,或,异或及移位运算的相关文章

hihoCoder.1509.异或排序(位运算 思路)

题目链接 \(Description\) 给定长为\(n\)的序列\(A\).求有多少\(S\),满足\(0\leq S<2^{60}\),且对于所有\(i\in[1,n-1]\),\(a[i]^{\wedge}S\leq a[i+1]^{\wedge}S\). \(n\leq20\). \(Solution\) 考虑对于\(a,b\),有哪些\(S\)满足\(a^{\wedge}S\leq b^{\wedge}S\). 找出\(a^{\wedge}b\)的最高位\(1\)(也就是\(a,b\)

Java的位运算符具体解释实例——与(&amp;amp;)、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包含了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.以下具体介绍每一个位运算符. 1.与运算符与运算符用符号“&”表示,其使用规律例如以下:两个操作数中位都为1,结果才为1,否则结果为0,比如以下的程序段.public class data13{public static void main(String[] args){int a=129;int b=

Java的位运算符详解实例——与(&amp;)、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包括了:"与"."非"."或"."异或".从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面详细介绍每个位运算符. 1.与运算符 与运算符用符号"&"表示,其使用规律如下: 两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段. public class data13 { publ

转: C语言中位运算符异或“∧”的作用

转自: http://blog.sina.com.cn/s/blog_74a459380101d6xl.html 异或运算符∧也称XOR运算符.它的规则是若参加运算的两个二进位同号,则结果为0(假):异号则为1(真).即0∧0=0,0∧1=1,1∧1=0.如: 即071∧052,结果为023(八进制数). “异或”的意思是判断两个相应的位值是否为“异”,为“异”(值不同)就取真(1),否则为(0). 下面举例说明∧运算符的应用: (1)使特定位翻转 假设有01111010,想使其低4位翻转,即1

Java的位运算符—— 与(&amp;)、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面详细介绍每个位运算符. 1.与运算符与运算符用符号“&”表示,其使用规律如下:两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段. public class data1 { public static void main(String[] args) { int a=129; int

[转]Java的位运算符详解实例——与(&amp;)、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面详细介绍每个位运算符. 1.与运算符与运算符用符号“&”表示,其使用规律如下:两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段.public class data13{public static void main(String[] args){int a=129;int b=128

Java的位运算符—与(&amp;)、非(~)、或(|)、异或(^)

位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面详细介绍每个位运算符. 1.与运算符与运算符用符号“&”表示,其使用规律如下:两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段.public class data13{public static void main(String[] args){int a=129;int b=128

C的|、||、&amp;、&amp;&amp;、异或、~、!运算

位运算     位运算的运算分量只能是整型或字符型数据,位运算把运算对象看作是由二进位组成的位串信息,按位完成指定的运算,得到位串信息的结果. 位运算符有:     &(按位与).|(按位或).^(按位异或).~ (按位取反). 其中,按位取反运算符是单目运算符,其余均为双目运算符.     位运算符的优先级从高到低,依次为~.&.^.|, 其中~的结合方向自右至左,且优先级高于算术运算符,其余运算符的结合方向都是自左至右,且优先级低于关系运算符.    (1)按位与运算符(&) 

Java学习之运算符

程序的很多地方都会用到数学运算,作为一门程序语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 其他运算符 算术运算符 算术运算符用在数学表达式中,它们的作用和在数学中的作用一样.下表列出了所有的算术运算符. 操作符 描述 + 加法 - 相加运算符两侧的值 二元运算符或二目运算符,对两个操作数处理 - 减法 - 左操作数减去右操作数 * 乘法 - 相乘操作符两侧的值 / 除法 - 左操作数除以右操作数 % 取