下面的位运算符在现实世界中有哪些用例?

和 XOR 不 或 左/右转


当前回答

& =和: 屏蔽掉特定的位。 您正在定义应该显示的特定位 或者不显示。0x0 & x将清除字节中的所有位,而0xFF不会改变x。 0x0F将显示较低位置的位。

转换: 要将较短的变量转换为具有位标识的较长的变量,必须调整位,因为int类型中的-1是0xFFFFFFFF,而long类型中的-1是0xffffffffffffffffff。为了保护 转换后应用掩码的标识。

| =或 位设置。如果已经设置了位,则位将独立设置。许多数据结构(位字段)有IS_HSET = 0, IS_VSET = 1这样的标志,可以独立设置。 要设置标志,您应用IS_HSET | IS_VSET(在C和汇编中,这是非常方便阅读的)

^ = XOR 找出相同或不同的部分。

~ =不 比特翻转。

可以证明,所有可能的局部位操作都可以通过这些操作来实现。 如果你愿意,你可以通过位操作来实现ADD指令。

以下是一些妙招:

http://www.ugcs.caltech.edu/~wnoise/base2.html http://www.jjj.de/bitwizardry/bitwizardrypage.html

其他回答

例如,我使用它们从打包的颜色值中获取RGB(A)值。

似乎没有人提到定点数学。

(是的,我老了,好吗?)

在当今现代语言的抽象世界里,没有太多。File IO是一个容易想到的方法,尽管它是在已经实现的东西上执行按位操作,而不是实现使用按位操作的东西。尽管如此,作为一个简单的例子,这段代码演示了在c#中删除文件上的只读属性(这样它就可以与指定FileMode.Create的新FileStream一起使用):

//Hidden files posses some extra attibutes that make the FileStream throw an exception
//even with FileMode.Create (if exists -> overwrite) so delete it and don't worry about it!
if(File.Exists(targetName))
{
    FileAttributes attributes = File.GetAttributes(targetName);

    if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
        File.SetAttributes(targetName, attributes & (~FileAttributes.ReadOnly));

    File.Delete(targetName);
}

As far as custom implementations, here's a recent example: I created a "message center" for sending secure messages from one installation of our distributed application to another. Basically, it's analogous to email, complete with Inbox, Outbox, Sent, etc, but it also has guaranteed delivery with read receipts, so there are additional subfolders beyond "inbox" and "sent." What this amounted to was a requirement for me to define generically what's "in the inbox" or what's "in the sent folder". Of the sent folder, I need to know what's read and what's unread. Of what's unread, I need to know what's received and what's not received. I use this information to build a dynamic where clause which filters a local datasource and displays the appropriate information.

下面是枚举是如何组合在一起的:

    public enum MemoView :int
    {
        InboundMemos = 1,                   //     0000 0001
        InboundMemosForMyOrders = 3,        //     0000 0011
        SentMemosAll = 16,                  //     0001 0000
        SentMemosNotReceived = 48,          //     0011
        SentMemosReceivedNotRead = 80,      //     0101
        SentMemosRead = 144,                //     1001
        Outbox = 272,                       //0001 0001 0000
        OutBoxErrors = 784                  //0011 0001 0000
    }

你明白这是怎么回事了吗?通过与“收件箱”枚举值InboundMemos加上(&),我知道InboundMemosForMyOrders在收件箱中。

下面是该方法的简化版本,它构建并返回为当前选择的文件夹定义视图的过滤器:

    private string GetFilterForView(MemoView view, DefaultableBoolean readOnly)
    {
        string filter = string.Empty;
        if((view & MemoView.InboundMemos) == MemoView.InboundMemos)
        {
            filter = "<inbox filter conditions>";

            if((view & MemoView.InboundMemosForMyOrders) == MemoView.InboundMemosForMyOrders)
            {
                filter += "<my memo filter conditions>";
            }
        }
        else if((view & MemoView.SentMemosAll) == MemoView.SentMemosAll)
        {
            //all sent items have originating system = to local
            filter = "<memos leaving current system>";

            if((view & MemoView.Outbox) == MemoView.Outbox)
            {
                ...
            }
            else
            {
                //sent sub folders
                filter += "<all sent items>";

                if((view & MemoView.SentMemosNotReceived) == MemoView.SentMemosNotReceived)
                {
                    if((view & MemoView.SentMemosReceivedNotRead) == MemoView.SentMemosReceivedNotRead)
                    {
                        filter += "<not received and not read conditions>";
                    }
                    else
                        filter += "<received and not read conditions>";
                }
            }
        }

        return filter;
    }

非常简单,但在抽象级别上是一个整洁的实现,通常不需要按位操作。

如果你想计算你的数字mod(%) 2的某次方,你可以使用yourNumber & 2^N-1,在这种情况下,它与yourNumber % 2^N相同。

number % 16 = number & 15;
number % 128 = number & 127;

这可能只是作为模数运算的一种替代品有用,它的红利很大,是2^N。但即便如此,在我在。net 2.0上的测试中,它相对于模运算的速度提升也可以忽略不计。我怀疑现代编译器已经执行了这样的优化。有人知道更多吗?

还没人提到过收藏。有时您有一个较小的可能值集合,比如只有10或20个可能值,您希望将其中一些值保存在一个集合中。当然,您可以使用常规的Set实现,它很可能使用支持哈希表。但由于可能值的集合是如此之小,这实际上只是浪费时间和空间。相反,您可以将集合存储在单个int或长值中,这正是java EnumSet所做的,如果我没记错的话。