What does this sign exactly mean? |=

前端 未结 5 546
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-13 05:18

|=

I\'m curious to learn about this operator, I\'ve seen this notation used while setting flags in Java.

for example:

notification.flags |=         


        
相关标签:
5条回答
  • 2021-01-13 05:39

    It is equivalent to

    notification.flags = notification.flags | Notification.FLAG_AUTO_CANCEL;
    

    where | is bitwise OR operator which OR the two variables bit-by-bit.

    It is well known by itself. There are also +=, -=, *=, /=, %=, &=, ^=.

    0 讨论(0)
  • 2021-01-13 05:42

    This syntax is also available in C/C++ and other languages. It is a bitwise OR and the same as:

    notification.flags = notification.flags | Notification.FLAG_AUTO_CANCEL;
    

    and similar to other operators like addition, subtraction, etc. For example:

    i += 5;
    

    is the same as:

    i = i + 5;
    
    0 讨论(0)
  • 2021-01-13 05:45

    Does it perform some kind of bit manipulation?

    Yes. It "OR"s the right-hand-side operand into the left-hand-side one.

    What does this mark exactly do?

    It's an assignment coupled with an OR.

    Are there any other well known signs such as this?

    There are plenty: +=, -=, *=, /=, %=, &=, and so on. Collectively, they are called compound assignment operators. They are described in section 15.26.2 of the Java Language Specification.

    0 讨论(0)
  • 2021-01-13 05:48

    It is called bitwise or operator. For example,

    5     = 0000 0101
    2     = 0000 0010
    5 | 2 = 0000 0111
          = 14
    

    So, this concept is used when a same option can use multiple values.

    As an example, consider a variable flags equal to one.

    int flags = 1;
    

    Now, if a flag value of 4 is added to it with bitwise or,

    flags |= 4;  // 0
    

    You can determine whether 4 was applied on flags with the bitwise and.

    if (flags & 4 == 4)  // returns true
    

    If that flag has been applied on the flags, bitwise and returns flag. In this way we can use bitwise and & bitwise or.

    Hope this helps.

    0 讨论(0)
  • 2021-01-13 05:51

    (1) Does it perform some kind of bit manipulation?

    If you use | with numeric operands then yes, it will be bitwise OR, if you use it on boolean operands it will be logical (non-short-circuit) OR. Example

    Logical OR: lets say that 1 represents true and 0 false

    +---+---+-------+
    | p | q | (p|q) |
    +---+---+-------+
    | 0 | 0 |   0   |
    | 0 | 1 |   1   |
    | 1 | 0 |   1   |
    | 1 | 1 |   1   |
    +---+---+-------+
    

    Bitwise OR will perform similar operation as boolean but will use corresponding bits

    decimal   binary
    6       = 00110
    3       = 00011
    OR -------------
              00111
    

    (2) What does this mark exactly do?

    x |= y is the same as x = x | y so it will calculate x | y and store it in x.

    (3) Are there any other well known signs similar to this?

    Yes, every arithmetic, bitwise or bit shift operator can be used this way: += -= *= /= %= &= ^= |= <<= >>= >>>=


    Here are some additional informations about usage of |= in

    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    

    Lets say that we have five properties.

    Property1 
    Property2
    Property3
    Property4
    Property5
    

    We can use last five bits of number to represents situations where we have (1) or don't have (0) some property.

    ...00xxxxx
         │││││
         ││││└─ flag for Property1
         │││└── flag for Property2
         ││└─── flag for Property3 
         │└──── flag for Property4
         └───── flag for Property5
    

    Now, lets say that we want to use only properties 1, 2 and 4. To do this we have to set bits indexed with 0, 1 and 3 to value 1 like

    ...0001101
         │││││
         ││││└─ (1) has Property1
         │││└── (0) no Property2
         ││└─── (1) has Property3
         │└──── (1) has Property4
         └───── (0) no Property5
    

    In other words we have to produce number 13 (= **1***8 + **1***4 + **0***2 + **1***1). We can do this with | OR bitwise operator 8|4|1 because

       8 = ...001000
       4 = ...000100
       1 = ...000001
    OR -------------
      13 = ...001101
    

    But to avoid magic numbers we can create constants that will represents our properties in bit world. So we can create

    public class MyProperties {
    
        //...
        public static final int PROPERTY_1 = 0b0000_0001; // = 1
        public static final int PROPERTY_2 = 0b0000_0010; // = 2
        public static final int PROPERTY_3 = 0b0000_0100; // = 4
        public static final int PROPERTY_4 = 0b0000_1000; // = 8
        public static final int PROPERTY_5 = 0b0001_0000; // = 16
        //...
        //rest of code: methods, constructors, other fields
    }
    

    and use it later like

    int context = Properties.PROPERTY_1|Properties.PROPERTY_2|Properties.PROPERTY_4
    

    which is more readable than int context = 8|4|1.


    Now if we want to change our context and lets say add PROPERTY_3 we can use

    context = context | Properties.PROPERTY_3;
    

    or shorter version based on compound assignments operators

    context |= Properties.PROPERTY_3;
    

    which will do this calculations

       context    = 000...00001101
       PROPERTY_3 = 000...00000010
    OR ------------------------
                    000...00001111
    

    (main difference between adding value of PROPERTY_3 to context and using bitwise OR | is that when context will already have PROPERTY_3 set to 1 then OR will no effect it).


    Now if you take a look here idea of using single bits as flags for properties was used in Notification class, where FLAG_AUTO_CANCEL constant has value 16 (0x010 in hexadecimal, 0b0001_0000 in binary).

    0 讨论(0)
提交回复
热议问题