|=
I'm curious to learn about this operator,
I've seen this notation used while setting flags in Java.
for example:
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Does it perform some kind of bit manipulation?
What does this mark exactly do?
Are there any other well known signs similar to this?
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 +=, -=, *=, /=, %=, &=, ^=.
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;
(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).
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.
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.
Related
I am using java SWT, which has a bunch of bit flags and operations I can use, but I'm not familiar with them.
To better explain, I have a style
style = SWT.A | SWT.B
Which basically translates to having style A AND B. I know that this is because
A = 0001
B = 0100
A | B = 0101 (bitwise or)
But I haven't played with bits enough to know all the things I can do, this is all I know
style |= A; // style adds flag A
style &= ~B; // style removes flag B
Do I have something like +0 at my disposal? For ternary operations.
style ?= question ? "+ style A" : "as is, no change"
I'm thinking maybe
style = question ? style | A : style;
style = question ? style & ~B : style;
But I'm not sure.
Anything else that would be useful?
There is also exclusive OR.
Exclusive OR (aka XOR) says in shorthand, one or the other but not both. So if you XOR 0 and 1 together it will return a 1. Otherwise a 0. And don't forget that these bitwise operators also operate on boolean values.
int A = 0b0001;
int B = 0b0100;
// A | B = 0101 (bitwise or)
style ^= A; // If off, turn on. If on, turn off.
style = A|B; // 0101
style ^= A; // style now equals 0100
style ^= A; // style now equals 0101
You can also swap with it.
int a = 23;
int b = 47;
a ^= b;
b ^= a;
a ^= b;
Now a == 47 and b == 23
And lastly, there is another use for bitwise operators. Defeating short circuiting of if statements. Here is an example:
int a = 5;
int b = 8;
// here a is true, no need to evaluate second part, it is short circuited.
if (a == 5 || ++b == 7) {
System.out.println(a + " " + b);
}
// but here the second part is evaluated and b is incremented.
if (a == 5 | ++b == 7) {
System.out.println(a + " " + b);
}
I can't remember every using it this way and it can cause difficult to find bugs in your program. But it's a feature.
I did some android stuff and found strange java code snippet.
I checked following with j2se and it gives commented results(without "prints").
Java code snippet looked like following:
class A{
public static void main(String[] args) {
method(1 | 2); //prints 3
method(1 | 2 | 3); //prints 3
method(1 | 2 | 3 | 4);//prints 7
}
public static void method(int value) {
System.out.println(value);
}
}
My question is what is happening here?
Bitwise OR
1 | 2 = '01' | '10' = 11 = 3
1 | 2 | 3 = '01' | '10' | '11' = 11 = 3
1 | 2 | 3 | 4 = '01' | '10' | '11' | '100' = 111 = 7
The | is a bitwise-OR operator.
It's applying an OR to the numeric values. Easier to see in binary:
1 | 2 | 3 | 4
1 is 0...00000001
2 is 0...00000010
3 is 0...00000011
4 is 0...00000100
OR: 0...00000111 bitwise OR of all values
0...00000111 = 7
It's not passing "multiple values", it's an arithmetic expression that evaluates to a single value.
However, it's frequently used to pass e.g. sets of "boolean" flags, where each flag is represented by a bit. For example:
static final int FLAG_CRISPY = 1; // 00000001 binary
static final int FLAG_SMOKED = 2; // 00000010 binary
static final int FLAG_ENDLESS = 4; // 00000100 binary
Then you may have a method:
void makeBacon (int flags) {
if ((flags & FLAG_CRISPY) != 0) // bitwise AND to check for flag
... flag is set
if ((flags & FLAG_SMOKED) != 0) // bitwise AND to check for flag
... flag is set
if ((flags & FLAG_ENDLESS) != 0) // bitwise AND to check for flag
... flag is set
}
And you can call it like:
makeBacon(FLAG_SMOKED | FLAG_ENDLESS);
Defining flags like this is convenient because you can modify the set of flags as the program evolves without having to make any changes to the method interface. It's also sometimes useful to be able to encapsulate a large set of options in a single int (e.g. when storing data to a binary file or sending over a network).
The official tutorial on bitwise and bit-shift operators has more information about other related operators (e.g. AND, XOR, left shift, right shift).
This is a code i am seeing for some time.
i wonder how the code works.
public static final int MULTI = 1 << 1;
public static final int SINGLE = 1 << 2;
public static final int READ_ONLY = 1 << 3;
SWT.MULTI | SWT.SINGLE | SWT.READ_ONLY
i went deep into the class implementation of TableViewer(Composite parent, int style) in search for the answer but didnt find much.
I found this code, but didnt understand much
static int checkBits (int style, int int0, int int1, int int2, int int3, int int4, int int5) {
int mask = int0 | int1 | int2 | int3 | int4 | int5;
if ((style & mask) == 0) style |= int0;
if ((style & int0) != 0) style = (style & ~mask) | int0;
if ((style & int1) != 0) style = (style & ~mask) | int1;
if ((style & int2) != 0) style = (style & ~mask) | int2;
if ((style & int3) != 0) style = (style & ~mask) | int3;
if ((style & int4) != 0) style = (style & ~mask) | int4;
if ((style & int5) != 0) style = (style & ~mask) | int5;
return style;
}
Packing Bits Together
Let's take a look at this code.
public static final int MULTI = 1 << 1;
public static final int SINGLE = 1 << 2;
public static final int READ_ONLY = 1 << 3;
The "<<" operator means shift the bits to the left. The number after the "<<" operator tells us how many bits to shift.
So, another way of writing the code would be.
public static final int MULTI = 2;
public static final int SINGLE = 4;
public static final int READ_ONLY = 8;
By defining the flags this way, the values can be OR'd ("added") together and saved in one byte or one integer.
SWT.MULTI | SWT.SINGLE
This is saying to OR the bits of the two values together. But what does that mean?
In this case, since we've defined our values as a single bit, it's the same as adding the values.
MULTI = 2
SINGLE = 4
Therefore, the status value is 6 (2 + 4).
Now remember, we're not adding. Because we're using bits, the effect is the same as if we're adding.
Unpacking Bits
The second bit of code you've posted basically takes the 6 that we came up with, and splits it back into 2 and 4. It works by checking each bit, one at a time, and seeing if it's present.
Let's take one line, and see what it's doing.
if ((style & int1) != 0) style = (style & ~mask) | int1;
int1 represents one of the style bits. For the sake of this discussion, let's say that it is MULTI with a value of 2.
The first part (the if condition) tests for whether or not the bit is set in the style integer.
The second part is a bit trickier. (Bit, get it. Very punny.)
The value of mask is given in the code.
int mask = int0 | int1 | int2 | int3 | int4 | int5;
This is just all of the status values OR'd together. From our original example of MULTI, SINGLE, and READ_ONLY, that gives us a mask of x'0E' or 14. Through the rest of this discussion, I'll be using hexadecimal.
Status Bit Present
Now, back to the line we're talking about.
if ((style & int1) != 0) style = (style & ~mask) | int1;
style & int1 is an AND operation. That means the bit has to be set in both style and int1. Style is x'06' (2 + 4) from when we set it before. int1 is x'02'. When you AND x'06' and x'02', you get x'02', which makes the value of the if true.
~mask converts the x'0E' into x'F1'. In other words, all of the bits are flipped from 0 to 1 and 1 to 0.
style & ~mask is an AND operation. When you AND x'06' and x'F1', you get x'00'. In other words, none of the bits match up.
We said earlier that int1 is MULTI, with the value of 2 or x'02'. Now we do an OR operation, which we explained before. ORing x'00' and x'02' gives us x'02', which is the MULTI value that we wanted to extract.
Status Bit Not Present
The other alternative (when the status bit is not present) leads to a slightly different result. We didn't set READ_ONLY, so lets go through that calculation.
READ_ONLY is x'08'. Style is x'06' When you AND those values together in the if
if ((style & int1) != 0) style = (style & ~mask) | int1;
you get x'00', which causes the value of the if to be false.
Justification
The original reason for putting several status values into one byte or word was to save memory. This was important 40 years ago when computer memory was limited. Now, it's done for convenience in passing status around. Rather than passing 7 or 15 different status indicators from one method to another, you pass one status indicator.
The tradeoff, as you have seen, is that it takes a bit of code to extract the status bits so you can use them.
All,
I have been practicing coding problems online. Currently I am working on a problem statement Problems where we need to convert Big Endian <-> little endian. But I am not able to jot down the steps considering the example given as:
123456789 converts to 365779719
The logic I am considering is :
1 > Get the integer value (Since I am on Windows x86, the input is Little endian)
2 > Generate the hex representation of the same.
3 > Reverse the representation and generate the big endian integer value
But I am obviously missing something here.
Can anyone please guide me. I am coding in Java 1.5
Since a great part of writing software is about reusing existing solutions, the first thing should always be a look into the documentation for your language/library.
reverse = Integer.reverseBytes(x);
I don't know how efficient this function is, but for toggling lots of numbers, a ByteBuffer should offer decent performance.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
...
int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);
buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);
As eversor pointed out in the comments, ByteBuffer.putInt() is an optional method, and may not be available on all Java implementations.
The DIY Approach
Stacker's answer is pretty neat, but it is possible to improve upon it.
reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
We can get rid of the parentheses by adapting the bitmasks. E. g., (a & 0xFF)<<8 is equivalent to a<<8 & 0xFF00. The rightmost parentheses were not necessary anyway.
reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;
Since the left shift shifts in zero bits, the first mask is redundant. We can get rid of the rightmost mask by using the logical shift operator, which shifts in only zero bits.
reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;
Operator precedence here, the gritty details on shift operators are in the Java Language Specification
Check this out
int little2big(int i) {
return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B. To convert that number, it needs to go to 0x1B000000... With your example, the hex representation of 123456789 is 0x075BCD15 which needs to go to 0x15CD5B07 or in decimal form 365779719.
The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff takes the lowest byte from i, the << 24 then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.
For example code, take a look at this utility.
Java primitive wrapper classes support byte reversing since 1.5 using reverseBytes method.
Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)
Just a contribution for those who are looking for this answer in 2018.
I think this can also help:
int littleToBig(int i)
{
int b0,b1,b2,b3;
b0 = (i&0x000000ff)>>0;
b1 = (i&0x0000ff00)>>8;
b2 = (i&0x00ff0000)>>16;
b3 = (i&0xff000000)>>24;
return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}
Just use the static function (reverseBytes(int i)) in java which is under Integer Wrapper class
Integer i=Integer.reverseBytes(123456789);
System.out.println(i);
output:
365779719
the following method reverses the order of bits in a byte value:
public static byte reverseBitOrder(byte b) {
int converted = 0x00;
converted ^= (b & 0b1000_0000) >> 7;
converted ^= (b & 0b0100_0000) >> 5;
converted ^= (b & 0b0010_0000) >> 3;
converted ^= (b & 0b0001_0000) >> 1;
converted ^= (b & 0b0000_1000) << 1;
converted ^= (b & 0b0000_0100) << 3;
converted ^= (b & 0b0000_0010) << 5;
converted ^= (b & 0b0000_0001) << 7;
return (byte) (converted & 0xFF);
}
While reading the Android guide to Notifications, I stumbled across this:
Adding vibration
You can alert the user with the the default vibration pattern or with a
vibration pattern defined by your application.
To use the default pattern, add "DEFAULT_VIBRATE" to the defaults field:
notification.defaults |= Notification.DEFAULT_VIBRATE;
What this does is clear: it adds the DEFAULT_VIBRATE flag to the default flags of the notification object.
But what does the |= operator do in Java?
It looks like an "OR", but how does it work?
Can you provide an example using numbers?
Thanks
|= is a bitwise-OR-assignment operator. It takes the current value of the LHS, bitwise-ors the RHS, and assigns the value back to the LHS (in a similar fashion to += does with addition).
For example:
foo = 32; // 32 = 0b00100000
bar = 9; // 9 = 0b00001001
baz = 10; // 10 = 0b00001010
foo |= bar; // 32 | 9 = 0b00101001 = 41
// now foo = 41
foo |= baz; // 41 | 10 = 0b00101011 = 43
// now foo = 43
a |= x is a = a | x, and | is "bitwise inclusive OR"
Whenever such questions arise, check the official tutorial on operators.
Each operator has an assignment form:
+= -= *= /= %= &= ^= |= <<= >>= >>>=
Where a OP= x is translated to a = a OP x
And about bitwise operations:
0101 (decimal 5)
OR 0011 (decimal 3)
= 0111 (decimal 7)
The bitwise OR may be used in situations where a set of bits are used as flags; the bits in a single binary numeral may each represent a distinct Boolean variable. Applying the bitwise OR operation to the numeral along with a bit pattern containing 1 in some positions will result in a new numeral with those bits set.
It is a short hand notation for performing a bitwise OR and an assignment in one step.
x |= y is equivalent to x = x | y
This can be done with many operators, for example:
x += y
x -= y
x /= y
x *= y
etc.
An example of the bitwise OR using numbers.. if either bit is set in the operands the bit will be set in the result. So, if:
x = 0001 and
y = 1100 then
--------
r = 1101
In this case, notification.defaults is a bit array. By using |=, you're adding Notification.DEFAULT_VIBRATE to the set of default options. Inside Notification, it is likely that the presence of this particular value will be checked for like so:
notification.defaults & Notification.DEFAULT_VIBRATE != 0 // Present
This is the bit wise OR operator. If notifications.default is 0b00000001 in binary form and Notification.DEFAULT_VIBRATE is 0b11000000, then the result will be 0b11000001.
bitwise OR operator