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
Related
If I want to set the 37th bit of a long to 1, I believe my code would look something like this:
long l = 0;
l |= 0b1 << 37;
However, this doesn't work because a long cannot shift by more than 31 bits. This confuses me because Oracle documentation says longs are 64 bit. (https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html)
I have taken a look at How do I bit shift a long by more than 32 bits?, but this seems to only work of c/c++.
I want to be able to toggle bits for a data type that has 64 bits. How would I do that in java?
long l;
l = 0;
l |= 0b1 << 37;
System.out.println(l);
// Outputs 32
l = 0;
l |= 0b1L << 37;
System.out.println(l);
// Outputs 137438953472
The problem you're running into is that your operation breaks down like this:
l |= 0b1 << 37;
Turns into, in sequence:
int _temp = 1 << 37;
l |= (long) _temp;
The reason it's like that is because 0b1, or any numeric literal that lacks a decimal part and a trailing letter to indicate what kind of literal you want (D/F/L for double/float/long), is therefore an int, period. You then left-shift this int value (1; 0b1 is just a weird way to write 1 after all) by 37. The spec of left-shift states that the right-hand operator of a shift operation only considers the lower 5 bits for int shifts and the lower 6 for long shifts. Because otherwise you'd just be making the value 0. Thus, someInt << 37 is a weird way of writing someInt << 5.
The solution is to make sure that your shift operation is actually happening on longs. There are many, many ways to make that happen.
Use a long literal
By writing a trailing L. It can be written in either case, but style guides and developers will egg your house if you use a lowercase l because duh that is incredibly stupid, don't do that. It looks like a 1. Thus:
l |= 1L << 37; // or if you must, 0b1L works too
One step at a time.
long temp = 1;
temp <<= 37;
l |= temp;
Cast it
l |= ((long) 0b1) << 37;
These will all get the job done: They all end up having the << operation be in 'long mode' (which occurs if the LHS is of type long, which it is, in all these 3 examples).
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'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.
I'm trying to decode somebody's byte array and I'm stuck at this part:
< state > ::= "01" <i>(2 bits) for A</i>
"10" <i>(2 bits) for B</i>
"11" <i>(2 bits) for C</i>
I think this wants me to look at the next 2 bits of the next byte. Would that mean the least or most significant digits of the byte? I suppose I would just throw away the last 6 bits if it means the least significant?
I found this code for looking at the bits of a byte:
for (int i = 0; i < byteArray.Length; i++)
{
byte b = byteArray[i];
byte mask = 0x01;
for (int j = 0; j < 8; j++)
{
bool value = b & mask;
mask << 1;
}
}
Can someone expand on what this does exactly?
Just to give you a start:
To extract individual bits of a byte, you use "&", called the bitwise and operator. The bitwise and operation means "preserve all bits which are set on both sides". E.g. when you calculate the bitwise-and of two bytes, e.g. 00000011 & 00000010, then the result is 00000010, because only the bit at the second last position is set in both sides.
In java programming language, the very same example looks like this:
int a = 3;
int b = 2;
int bitwiseAndResult = a & b; // bitwiseAndResult will be equal to 2 after this
Now to examine if the n'th bit of some int is set, you can do this:
int intToExamine = ...;
if ((intToExamine >> n)) & 1 != 0) {
// here we know that the n'th bit was set
}
The >> is called the bitshift operator. It simply shifts the bits from left to right, like this: 00011010 >> 2 will have the result 00000110.
So from the above you can see that for extracting the n'th bit of some value, you first shift the n'th bit to position 0 (note that the first bit is bit 0, not bit 1), and then you use the bitwise and operator (&) to only keep that bit 0.
Here are some simple examples of bitwise and bit shift operators:
http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm
This seems fairly straightforward, but I cant find an answer. If I have an int X, what is the best way to get N least significant bits from this int, in Java?
This should work for all non-negative N < 33 32:
x & ((1 << N) - 1)
It's worth elaborating on how this works for N == 31 and N == 32. For N == 31, we get 1 << N == Integer.MIN_VALUE. When you subtract 1 from that, Java silently wraps around to Integer.MAX_VALUE, which is exactly what you need. For N == 32, the 1 bit is shifted completely out, so 1 << N == 0; then (1 << N) - 1 == -1, which is all 32 bits set.
For N == 32, this unfortunately doesn't work because (thanks, #zstring!) the << operator only shifts by the right side mod 32. Instead, if you want to avoid testing for that case specially, you could use:
x & ((int)(1L << N) - 1)
By shifting a long, you get the full 32-bit shift, which, after casting back to an int, gets you 0. Subtracting 1 gives you -1 and x & -1 is just x for any int value x (and x is the value of the lower 32 bits of x).
Ted's approach is likely to be faster but here is another approach
x << -N >>> -N
This shift all the bit up and then down to chop off the top bits.
int i = -1;
System.out.println(Integer.toBinaryString(i));
i = i << -5 >>> -5;
System.out.println(Integer.toBinaryString(i));
prints
11111111111111111111111111111111
11111
You can also use a mask. If you use the & bitwise operator you can then remove whatever bit you would want to remove (say the highest x bits);
int mask = 0x7FFFFFFF //Example mask where you will remove the
// most significant bit
// (0x7 = 0111b and 0xF = 1111b).
int result = numberToProcess & mask; //And apply the mask with the &bitwise op.
The disadvantage to this is that you will need to make a mask for each bit, so perhaps this is better seen as another method of approach in general.