一尘不染

按位运算的实际应用

c#

按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。

7年前关闭。

  1. 您对位运算使用了什么?
  2. 他们为什么这么方便?
  3. 有人可以推荐一个非常简单的教程吗?

阅读 383

收藏
2020-05-19

共1个答案

一尘不染

尽管每个人似乎都对标志用例感兴趣,但这并不是按位运算符的唯一应用(尽管可能是最常见的)。C#是一种足够高级的语言,可能很少使用其他技术,但是仍然值得了解它们。这是我能想到的:


<<>>运营商可以迅速地乘的2场的力量,.NET
JIT优化可能会为你做这个(和其他语言以及任何像样的编译器),但如果你每微秒真的心乱了,你也许可以写这个来确定。

这些运算符的另一个常用用法是将两个16位整数填充为一个32位整数。喜欢:

int Result = (shortIntA << 16 ) | shortIntB;

直接与Win32函数进行接口时很常见,有时出于传统原因有时会使用此技巧。

而且,当然,这些运算符在您想使经验不足的人困惑时很有用,例如在提供作业问题的答案时。:)

但是,在任何实际代码中,您都可以通过使用乘法来获得更好的效果,因为它具有更好的可读性,并且JIT
始终对其进行优化shlshr指令化,因此不会对性能造成任何影响。


^运算符(XOR)处理了很多奇怪的技巧。由于以下属性,它实际上是一个非常强大的运算符:

  • A^B == B^A
  • A^B^A == B
  • 如果知道,A^B就不可能说出什么AB是什么,但是如果您知道其中一个,就可以计算出另一个。
  • 运算符不会受到任何溢出的影响,例如乘法/除法/加法/减法。

使用此运算符时,我发现了一些技巧:

交换两个没有中间变量的整数变量:

A = A^B // A is now XOR of A and B
B = A^B // B is now the original A
A = A^B // A is now the original B

双链表,每个项目只有一个额外的变量。这在C#中几乎没有用,但对于每个字节都很重要的嵌入式系统的低级编程可能会派上用场。

这个想法是让您跟踪第一个项目的指针。最后一项的指针;而对于您跟踪的每个项目pointer_to_previous ^ pointer_to_next。这样,您可以从任一端遍历列表,但是开销仅为传统链接列表的一半。这是用于遍历的C ++代码:

ItemStruct *CurrentItem = FirstItem, *PreviousItem=NULL;
while (  CurrentItem != NULL )
{
    // Work with CurrentItem->Data

    ItemStruct *NextItem = CurrentItem->XorPointers ^ PreviousItem;
    PreviousItem = CurrentItem;
    CurrentItem = NextItem;
}

要从头开始遍历,只需将第一行从更改FirstItemLastItem。那是在那里节省的另一个内存。

^经常在C#中使用运算符的另一个地方是,我必须为我的类型(复合类型)计算HashCode时。喜欢:

class Person
{
    string FirstName;
    string LastName;
    int Age;

    public int override GetHashCode()
    {
        return (FirstName == null ? 0 : FirstName.GetHashCode()) ^
            (LastName == null ? 0 : LastName.GetHashCode()) ^
            Age.GetHashCode();
    }
}
2020-05-19