C# 什么时候按位操作合适

C# 什么时候按位操作合适,c#,algorithm,bit-manipulation,bit-shift,C#,Algorithm,Bit Manipulation,Bit Shift,我知道什么是位运算的基本前提(尽管我希望有一个“对于傻瓜”的解释);然而,我不知道什么时候使用这种技术是合适的 我的理解是,因此知道如何使用它们是有利的。鉴于情况已不再如此;是否仍然适合执行这些操作?如果是,出于什么目的,在什么条件下执行?(我对C#上下文特别感兴趣,但很高兴得到一般性的答案)问题不在于按位运算比整数运算快(尽管它们通常是这样),而是它们是不同的操作,用于不同的目的 从概念上讲,字节、短字符和整数是非常小的位数组,而按位运算符是布尔数组运算符。如今在C#中,按位运算符主要用于[F

我知道什么是位运算的基本前提(尽管我希望有一个“对于傻瓜”的解释);然而,我不知道什么时候使用这种技术是合适的


我的理解是,因此知道如何使用它们是有利的。鉴于情况已不再如此;是否仍然适合执行这些操作?如果是,出于什么目的,在什么条件下执行?(我对C#上下文特别感兴趣,但很高兴得到一般性的答案)

问题不在于按位运算比整数运算快(尽管它们通常是这样),而是它们是不同的操作,用于不同的目的


从概念上讲,字节、短字符和整数是非常小的位数组,而按位运算符是布尔数组运算符。如今在C#中,按位运算符主要用于
[Flags]
枚举和
GetHashCode
计算,但使用位数组的方法有很多种。

您是正确的,因为语言提供了按位运算,所以您不应该因为可以使用而使用它们。我见过人们在处理简单布尔运算时使用位运算符,但这不是他们的目的


在处理数据块与字节边界不对齐的数据结构时,按位运算符非常有用。通常,这是在带宽(或一般内存占用)非常重要时完成的。我从事RTP视频流软件的工作,逐位操作用于读取/构造RTP传输包以及读取视频编解码器流,视频编解码器流通常使用位而不是字节进行编码。

当空间非常宝贵时,它们在嵌入式控制情况下非常有用。例如,一个数据字节可以表示8个i/o位,掩码可以用于从i/o端口检索感兴趣的位(例如,如果
PIN0=1、PIN1=2、PIN2=4、PIN3=8等,则:

  • 要获得
    PIN0
    的值,我们可以说
    PORT0&PIN0==0
  • 要将
    PIN1
    设置为1,我们可以使用
    PORT0 |=PIN1
  • 要将
    PIN2
    设置为0,我们可以说
    PORT0&=~PIN2
除了嵌入式控制之外,我现在很少看到使用这种方法。在C#世界中,更常见的是看到每个感兴趣的值都有单独的布尔字段,因为这种开销对于现代硬件来说并不是什么大问题(尽管您可能会遇到一两种情况,其中使用位操作在单个变量中保留许多这样的标志)


还有一个有趣的图形应用程序。光标或边界框的一个巧妙技巧是通过将光标形状与下图异或来添加它们。再次执行相同的操作将生成原始图像。

我发现自己不时使用位运算符的一种方法是生成给定字符串的子集/使用二进制掩码,数组如下:(对不起,C++代码)< /P>
string s=“abcde”;

for(int i=0;i<1按位操作是快速检查可能在变量上设置的标志的好方法

下面的示例强调了对
标志
枚举使用逐位操作以及将填充位字段存储到数据库中的好处。然后可以轻松检查填充位字段,查看它是否包含
标志
枚举中的单个值或值的子集

示例:

Permission userPermissions = Permission.ManageUsers | Permission.CreateOrders;
public bool HasPermissions(Permission userPermissions, Permission permissionsToCheckFor)
{
    return permissionsToCheckFor == Permission.None ? 
        false : 
        (userPermissions & permissionsToCheckFor) == permissionsToCheckFor;
}
一个
User
数据库表,其中包含一个名为
Permission
tinyint
字段。该字段使用枚举创建的值填充,该值为2^n

[Flags]
public enum Permission : byte
{
    None = 0,
    ManageUsers = 1 << 0,
    CreateOrders = 1 << 1,
    PurchaseEquipment = 1 << 2,
    CancelOrders = 1 << 3,
}
权限检查示例:

Permission userPermissions = Permission.ManageUsers | Permission.CreateOrders;
public bool HasPermissions(Permission userPermissions, Permission permissionsToCheckFor)
{
    return permissionsToCheckFor == Permission.None ? 
        false : 
        (userPermissions & permissionsToCheckFor) == permissionsToCheckFor;
}

你是指移位之类的,还是所有的逻辑运算?没有移位。我理解逻辑运算。+1.我使用按位运算的实际例子-Base64/Base32编码/解码码(数据被认为是一次编码6或5位的位数组)。更一般地说,用于压缩/解压缩的代码通常使用按位运算将数据视为高位数组。这是一个很棒的示例。非常感谢。:-)@Maxim Gershkovich如果您使用clientI agree@HCP在数据库中查找值,您将不会立即看到userPermissions将是什么,这不是一种倒退吗?按位运算符会导致不必要的代码无法读取,因为有许多其他方法来编码此信息。1.速度/大小优化是我们唯一的真正原因除非你是在做嵌入式系统,否则我认为在今天的大多数系统上,没有什么正当的理由需要这种加速。在大多数大型项目中,可读性和调试能力的权衡对于速度来说是非常值得的。根据:如果:1.你花费ct枚举将用作非常频繁实例化的结构或类中的字段。2.您希望用户创建大型数组或枚举实例集合。3.您希望序列化大量枚举实例。@M1K,给定此示例,您还将如何对此信息进行编码?当然是您不是建议为每个权限设置一个位列吗?此示例不适用于速度/大小优化技术。它只是显示了一种简单的权限管理方法。就是这样。此外,您对MSDN的引用引用了与
标志
枚举根本不相关的不相关点!最后,位操作也是一个核心p编程概念。这两个核心概念都很容易理解和理解。