位移是否与我的预期相反?

Is bit shifting opposite from what I am expecting?

我今天用枚举和按位运算符做了一些测试,为了验证 Xcode 的功能,我创建了一系列测试。这是我将保留的完整要点 public.

https://gist.github.com/brennanMKE/ede1f685018e953da8a4

对于枚举,我设置了移位值,以便我可以使用按位运算符来检查值。这是 MyState 枚举的类型定义。

typedef NS_OPTIONS(NSUInteger, MyState) {
    MyStateNone                 = 0,            // (0000 = 0)
    MyStateOn                   = (1 << 0),     // (1000 = 1)
    MyStateOff                  = (1 << 1),     // (0100 = 2)
    MyStateEnabled              = (1 << 2),     // (0010 = 4)
    MyStateDisabled             = (1 << 3),     // (0001 = 8)
    MyStateOnAndEnabled         = MyStateOn | MyStateEnabled,   // 5
    MyStateOffAndDisabled       = MyStateOff | MyStateDisabled  // 10
};

您可以看到开、关、启用和禁用状态是按顺序排列的,这将允许移动值以将状态从开和启用更改为关和禁用。这些位将从 1010 变为 0101。

我认为应该是右移 (>>) 但在我的测试中它是左移。下面是测试函数。为什么它与我期望的相反的轮班操作员一起工作?也许我的理解与它的作用相反。好像是这样。

左移好像是在左边放一个0,把所有的位都移到右边。我认为这意味着左移意味着所有位都向左移动。有人可以澄清吗?谢谢

- (void)testBitShiftingToOnAndEnabled {
    // Note: shifting enum values is ill advised but useful academically

    MyState state = MyStateOffAndDisabled; // 0101 (10)
    NSLog(@"state: %lu", (unsigned long)state);
    // if both values are shifted 1 to the right it becomes off and disabled
    state >>= 1; // 1010 (5)
    NSLog(@"state: %lu", (unsigned long)state);

    XCTAssert(state == MyStateOnAndEnabled, @"Pass");
    XCTAssert(state == 5, @"Pass");
}

- (void)testBitShiftingToOffAndDisabled {
    // Note: shifting enum values is ill adviced but useful academically

    MyState state = MyStateOnAndEnabled; // 1010 (5)
    NSLog(@"state: %lu", (unsigned long)state);
    // if both values are shifted 1 to the left it becomes off and disabled
    state <<= 1; // 0101 (10)
    NSLog(@"state: %lu", (unsigned long)state);

    XCTAssert(state == MyStateOffAndDisabled, @"Pass");
    XCTAssert(state == 10, @"Pass");
}

表达式1<<2表示将值1的位向左移动2位。将 << 视为指向左侧的箭头。

二进制(8 位)的值 1

00000001

现在将位向左移动2位:

00000100

这就是 1<<2 将值 1 更改为 4 的原因。

你的误解是位序是从右到左的。

您的代码的更新注释:

typedef NS_OPTIONS(NSUInteger, MyState) {
    MyStateNone                 = 0,            // (0000 = 0)
    MyStateOn                   = (1 << 0),     // (0001 = 1)
    MyStateOff                  = (1 << 1),     // (0010 = 2)
    MyStateEnabled              = (1 << 2),     // (0100 = 4)
    MyStateDisabled             = (1 << 3),     // (1000 = 8)
    MyStateOnAndEnabled         = MyStateOn | MyStateEnabled,   // 5
    MyStateOffAndDisabled       = MyStateOff | MyStateDisabled  // 10
};

顺便说一句 - 这是基本的 C。None 这是 Objective-C 特有的。