Why would someone use the << operator in an enum declaration?

前端 未结 7 633
悲&欢浪女
悲&欢浪女 2020-12-29 19:13

I was looking at the code I have currently in my project and found something like this:

public enum MyEnum
{
    open     = 1 << 00,
    close    = 1 &         


        
相关标签:
7条回答
  • 2020-12-29 19:20

    This is to make an enum that you can combine.

    What it effectively means is this:

    public enum MyEnum
    {
        open = 1;
        close = 2;
        Maybe = 4;
        //...
    }
    

    This is just a more bulletproof method of creating a [Flags] enum.

    0 讨论(0)
  • 2020-12-29 19:21

    It is equal to powers of two.

    public enum SomeEnum
    {
        Enum1 = 1 << 0,    //1
        Enum2 = 1 << 1,    //2
        Enum3 = 1 << 2,    //4
        Enum4 = 1 << 3     //8
    }
    

    And with such enum you will have function which looks like this:

    void foo(unsigned ind flags)
    {
        for (int = 0; i < MAX_NUMS; i++)
            if (1 << i & flags)
            {
                //do some stuff...
                //parameter to that stuff probably is i either enum value
            }
    }
    

    And call to that function would be foo(Enum2 | Enum3); and it will do something with all given enum values.

    0 讨论(0)
  • 2020-12-29 19:23

    It's just meant to be a cleaner / more intuitive way of writing the bits. 1, 2, 3 is a more human-readable sequence than 0x1, 0x2, 0x4, etc.

    0 讨论(0)
  • 2020-12-29 19:30

    This allows you to do something like this:

    var myEnumValue = MyEnum.open | MyEnum.close;
    

    without needing to count bit values of multiples of 2.

    (like this):

    public enum MyEnum
    {
        open     = 1,
        close    = 2,
        Maybe    = 4,
        ........
    }
    
    0 讨论(0)
  • 2020-12-29 19:37

    Lots of answers here describing what this mechanic allows you to do, but not why you would want to use it. Here's why.

    Short version:

    This notation helps when interacting with other components and communicating with other engineers because it tells you explicitly what bit in a word is being set or clear instead of obscuring that information inside a numeric value.

    So I could call you up on the phone and say "Hey, what bit is for opening the file?" And you'd say, "Bit 0". And I'd write in my code open = 1 << 0. Because the number to the right of << tells you the bit number.

    .

    Long version:

    Traditionally bits in a word are numbered from right to left, starting at zero. So the least-significant bit is bit number 0 and you count up as you go toward the most-significant bit. There are several benefits to labeling bits this way.

    One benefit is that you can talk about the same bit regardless of word size. E.g., I could say that in both the 32-bit word 0x384A and 8-bit word 0x63, bits 6 and 1 are set. If you numbered your bits in the other direction, you couldn't do that.

    Another benefit is that a bit's value is simply 2 raised to the power of the bit position. E.g., binary 0101 has bits 2 and 0 set. Bit 2 contributes the value 4 (2^2) to the number, and bit 0 contributes the value 1 (2^0). So the number's value is of course 4 + 1 = 5.

    That long-winded background explanation brings us to the point: The << notation tells you the bit number just by looking at it.

    The number 1 by itself in the statement 1 << n is simply a single bit set in bit position 0. When you shift that number left, you're then moving that set bit to a different position in the number. Conveniently, the amount you shift tells you the bit number that will be set.

    1 << 5:   This means bit 5.   The value is 0x20.
    1 << 12:  This means bit 12.  The value is 0x40000.
    1 << 17:  This means bit 17.  The value is 0x1000000.
    1 << 54:  This means bit 54.  The value is 0x40000000000000.
              (You can probably see that this notation might be helpful if
              you're defining bits in a 64-bit number)
    

    This notation really comes in handy when you're interacting with another component, like mapping bits in a word to a hardware register. Like you might have a device that turns on when you write to bit 7. So the hardware engineer would write a data sheet that says bit 7 enables the device. And you'd write in your code ENABLE = 1 << 7. Easy as that.

    Oh shoot. The engineer just sent an errata to the datasheet saying that it was supposed to be bit 15, not bit 7. That's OK, just change the code to ENABLE = 1 << 15.

    What if ENABLE were actually when both bits 7 and 1 were set at the same time?

    ENABLE = (1 << 7) | (1 << 1).

    It might look weird and obtuse at first, but you'll get used to it. And you'll appreciate it if you ever explicitly need to know the bit number of something.

    0 讨论(0)
  • 2020-12-29 19:42

    This is usually used with bitfields, since it's clear what the pattern is, removes the need to manually calculate the correct values and hence reduces the chance of errors

    [Flags]
    public enum SomeBitField
    {
        open = 1 << 0    //1
        closed = 1 << 1  //2
        maybe = 1 << 2   //4
        other = 1 << 3   //8
        ...
    }
    
    0 讨论(0)
提交回复
热议问题