C# 位运算及应用

发布于:2025-07-27 ⋅ 阅读:(12) ⋅ 点赞:(0)

位运算符

运算符号

位逻辑运算

格式

~

运算

~a

&

运算

a & b

|

运算

a | b

^

异或运算

a ^ b

<<

左移运算

a<<num

num:移动位数

>>

右移运算

a>>num

非运算:~

运算规则:将0换成1,将1换成0

与运算:&

运算规则:1&0 = 0;1&1 = 1;0&0=0

算式

解析

结果

1&2

0001 & 0010 = 0000

0

5&6

0101 & 0110 = 0100

4

13&14

1101 & 1110 = 1100

12

或运算:|

运算规则:1|0 = 1;1|1 = 1;0|0=0

算式

解析

结果

1|2

0001 | 0010 = 0011

3

5|6

0101 | 0110 = 0111

7

13|14

1101 | 1110 = 1111

15

异或运算:^

运算规则:1^0 = 1;1^1 = 0;0^0=0 相同得0,相异得1

算式

解析

结果

1^2

0001 ^ 0010 = 0011

3

5^6

0101 ^ 0110 = 0011

3

13^14

1101 ^ 1110 = 0011

3

左移运算:<<

 运算规则:左移相当于乘. 左移一位相当于乘2;左移两位相当于乘4;左移三位相当于乘8。左移n位相当于乘以2的n次幂

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

例子:3<<3

算式

解析

结果

3<<3

00011 -> 11000   相当于 3乘以2的3次幂

24

右移运算:>>

运算规则:右移相当于整除. 右移一位相当于除以2;右移两位相当于除以4;右移三位相当于除以8。

右移n位相当于整除2的n次幂

  x>>1= x/2 
  x>>2= x/4 
  x>>3= x/8 
  x>>4=x/16

算式

解析

结果

3>>1

0011 -> 0001

1

16>>2

10000 -> 00100

4

应用

判断奇偶数

(x&1) == 0   true:偶数  false:奇数

用来替换使用取模运算来判断奇偶数(x%2 == 0)

使用位运算的实现会比使用取模运算的实现要快

实现和2的n次幂的乘除法

和2的n次幂的乘法

算术运算实现,速度较慢

public int Logic(int num,int count)
{
    return  num * (int)Math.Pow(2, count);
}

位运算实现,速度快

public int Logic(int num,int count)
{
    return num<<count;
}

 和2的n次幂的整除

算术运算实现,速度较慢

public int Logic(int num,int count)
{
    return  num / (int)Math.Pow(2, count);
}

位运算实现,速度快

public int Logic(int num,int count)
{
    return num>>count;
}

交换两个整数

普通实现:借助临时变量实现

int a = 1;
int b = 2;

int temp = a;
a = b;
b = temp;

位运算实现,不占用内存

int a = 1;
int b = 2;

a ^= b;
b ^= a;
a ^= b;

状态标志管理

1、开发中有时需要处理一个对象多个状态的情况,相关操作包括移除位标志添加位标志检查位标志

2、与普通实现方法相比(使用多个bool字段进行状态管理),使用位运算进行状态管理的优点有:节省内存、性能更好、更高效的网络传输。

3、枚举值必须是 2 的幂次方(即 1, 2, 4, 8, 16...),以便按位运算正确工作:

整数状态标志管理

int None = 0;       // 0000
int Read = 1;       // 0001
int Write = 2;      // 0010
int Execute = 4;    // 0100
int Delete = 8;     // 1000

int status = 0;
//添加位标志
status |= Read;
Debug.LogError(status);
status |= Write;
Debug.LogError(status);
status |= Execute;
Debug.LogError(status);
Debug.Log("---------------");
//检查标志位
Debug.LogError( (status&Read) == Read);
Debug.LogError( (status&Write) == Write);
Debug.LogError( (status&Execute) == Execute);
Debug.LogError( (status&Delete) == Delete);
Debug.Log("---------------");
//移除标志位
status &= ~Execute;
Debug.LogError( (status&Read) == Read);
Debug.LogError( (status&Write) == Write);
Debug.LogError( (status&Execute) == Execute);
Debug.LogError( (status&Delete) == Delete);

枚举状态标志管理

public enum Stauts
{
    None = 0,       // 0000
    Read = 1,       // 0001
    Write = 2,      // 0010
    Execute = 4,    // 0100
    Delete = 8      // 1000
}

var flag = Stauts.None;
//添加位标志
flag |= Stauts.Read;
Debug.LogError(flag);
flag |= Stauts.Write;
Debug.LogError(flag);
flag |= Stauts.Execute;
Debug.LogError(flag);
Debug.Log("---------------");
//检查标志位
Debug.LogError(  flag.HasFlag(Stauts.Read));
Debug.LogError( flag.HasFlag(Stauts.Write));
Debug.LogError( flag.HasFlag(Stauts.Execute));
Debug.LogError( flag.HasFlag(Stauts.Delete));
Debug.Log("---------------");
//移除标志位
flag &= ~Stauts.Execute;
Debug.LogError(  flag.HasFlag(Stauts.Read));
Debug.LogError( flag.HasFlag(Stauts.Write));
Debug.LogError( flag.HasFlag(Stauts.Execute));
Debug.LogError( flag.HasFlag(Stauts.Delete));

优缺点

位运算是直接对整数在二进制位级别进行操作的低级运算,在C#中合理使用可以带来显著优势,但也存在一些限制。

优点:

1、极高的性能

2、节省内存

缺点:

1、可读性较低

2、不好维护,调试困难

3、类型限制:仅适用整数类型,不能用于float、double、decimal等

建议

1、在使用位运算的代码处添加详细注释

2、将复杂操作逻辑进行封装

3、普通业务逻辑优先选择可读性更好的写法

 位运算如同C#中的"机械级工具",能显著提升性能,但滥用会增加代码维护成本。建议在性能分析确认瓶颈后再使用,并做好充分的文档说明。


网站公告

今日签到

点亮在社区的每一天
去签到