What does step ^= 1 mean in Java? - java

I know that ^ is the xor operator in Java. But I couldn't understand it in the following context.
int step = 0;
...
step ^=1;
Source: Google Code Jam 2014 (Participant's answer)
File Link : here

it goes under assignment operator category like
+= -= *= /= %= &= ^= |= <<= >>= >>>=
means
^= bitwise exclusive OR and assignment operator
step ^=1; as same as step = step ^ 1;

^ stands for XOR operator.
a ^= b is equivalent to a = a ^ b

step ^=1 means step = step xor 1. Similar to step += 1 which gets evaluated to step = step + 1
So ^= is short hand xor operator.
So xor table says:
operand1 operand2 output
0 0 0
0 1 1
1 0 1
1 1 0
so if my step is 1, then 1 xor 1 would be 0.

From Java Tutorials,
^
Assume integer variable A holds 60 and variable B holds 13 then:
Binary XOR Operator copies the bit if it is set in one operand but not both.(A ^ B) will give 49 which is 0011 0001
In your case it is,
step = step^1
and in result you get step=1
http://www.tutorialspoint.com/java/java_basic_operators.htm

As others have pointed out, step ^=1 flips the least significant bit of step. This makes even numbers get 1 bigger, and odd numbers get 1 smaller.
Examples:
0 --> 1
1 --> 0
7 --> 6
6 --> 7
-3 --> -4

Related

Difference between 2^0*2 and (2^0)*2?

I have expected both expression's will give same answer:
System.out.println(2^0*2);
System.out.println((2^0)*2);
Output:
2
4
Is there a specific reason why 2^0*2 = 2 and (2^0)*2 = 4?
You have wrongly assumed that ^ operator behaves the same like the exponentiation in math.
At the first sight you can see that ^ is understood as + operator. Actually it means bitwise XOR operator.
System.out.println(2^0*2); // 2 XOR 0 * 2 = 2
System.out.println((2^0)*2); // (2 XOR 0) * 2 = 4
System.out.println(2^4); // 2 XOR 4 = 6
The XOR is exclusive disjunction that outputs true only when inputs differ. Here is the whole trick:
2^0 = 2 XOR 0 = (0010) XOR (0000) = (0010) = 2
2^4 = 2 XOR 4 = (0010) XOR (0100) = (0110) = 6
check this link
http://bmanolov.free.fr/javaoperators.php
2^0*2=2
has higher priority thatn ^ so first you will evaluate 0*2 which is 0 and then xor it with 2 which will resutl 2
(2^0)*2
() has higher priority so you will first evaluate 2^0 then which is 2 then multiply it with 2
Operator Precedence
In your first example you calculate: 0*2 = 2 ^ 0 = 2
In your second example you calculate: 2 ^ 0 = 2 * 2 = 4

Finding odd/even numbers

I have been given this sample code for some exercises, and it shows how to find whether an integer is odd or even.
int x = 4;
if ( (x & 1) == 0 )
{
System.out.println("even");
}
else
{
System.out.println("odd");
}
But I dont understand why you do ' x & 1 '. What's the purpose of that?
In the binary representation of a number, any number with its least significant bit set to 0 is even. It would also be helpful to know what the & operator does.
For example 5 = 0101 (binary) and 1 = 0001 (binary). In this case, it compares 0101 with 0001.
You compare it bitwise, so the first bit would be 1 & 0 = 0. The second bit is 0 & 0 = 0. The third bit is 0 & 0 = 0. The last bit is 1 & 1 = 1.
So 5 & 1 = 0001, which is 1 in decimal. 1 == 0 evaluates to false for x = 5.
For all other even numbers, the least significant digit is 0, so any even number & 1 will always evaluate to 0.
That is because & performs a bitwise AND operation:
if ( (x & 1) == 0 )
Your code is as good as saying, print "Odd" if last binary digit of x is 1.
And it will work because all odd numbers will always have 1 as their last binary digit.
Consider this:
1 is 0001 in binary.
2 is 0010 in binary.
When (0001 & 0010) only those positions with both matched with 1 will remained as 1, which means:
0001 & 0010 gives you 0000 (0) // 1 & 2 = 0
Look at this pattern:
0001 & 0001 = 1 //1 & 1 = 1 (is odd)
0010 & 0001 = 0 //2 & 1 = 0 (is even)
0011 & 0001 = 1 //3 & 1 = 1 (is odd)
0100 & 0001 = 0 //4 & 1 = 0 (is even)
0101 & 0001 = 1 //5 & 1 = 1 (is odd)
0110 & 0001 = 0 //6 & 1 = 0 (is even)
It's a bitwise AND operation between the binary representation of the two numbers. Odd numbers always have their 1 bit set. Even numbers do not.
So, the ampersand AND == 0 is true for even numbers, but not for odd ones.
http://www.tutorialspoint.com/java/java_bitwise_operators_examples.htm
It evaluates the variable's binary value
Let's say x = 6 (110 in binary) and y = 7 (111)
Since we know that 1&0=0 and 1&1=1 (or true&false=false and true&true=true)
x & 1 == 0 // evaluates to true if x is even because
110
&001
----
000
y & 1 == 0 // evaluates to false because
111
&001
----
001
The LSB of a binary number is holding the information about Parity,
any odd numbers has LBS==1 and any even has LSB==0
so when you do a bitwise and you are multiplying bit by bit
against 1, the porpouse of this is to clear all other bits but leaving the LSB just like it is (that is why multpling by 1)
A binary number can be easily identified if it's odd or even just by looking at least significant bit, wheather it is set or not(1 or 0). If least significant bit is 1 then that's an odd number else it's an even.
Just check (number % 10) if true, its odd number, else even number.

Implementation logic behind adding two numbers without using +?

I found this code online. But, I am unable to get the logic behind the following code:
public static int add(int a, int b) {
if (b == 0) return a;
int sum = a ^ b; // add without carrying
System.out.println("sum is : "+sum);
int carry = (a & b) << 1; // carry, but don’t add
return add(sum, carry); // recurse
}
Let's look at an example (using 8 bits for simplicity)
a = 10010110
b = 00111101
a^b is the xor, which gives 1 for places where there is a 1 in one number and 0 in the other. In our example:
a^b = 10101011
Since 0 + 0 = 0, 0 + 1 = 1 and 1 + 0 = 1, the only columns left to deal with are the ones that have a 1 in both of the numbers. In our example, a^b is short by whatever the answer to
00010100
+ 00010100
is. In binary, 1 + 1 = 10, so the answer to the above sum is
00101000
or (a & b) << 1. Therefore the sum of a^b and (a & b) << 1 is the same as a + b.
So, assuming the process is guaranteed to terminate, the answer will be correct. But the process will terminate because each time we call sum recursively the second parameter has at least one more 0 at the end, due to the bit shift <<. Therefore, we are guaranteed to eventually end up with the second argument consisting entirely of 0s, so that the line if (b == 0) return a; can end the process and give us an answer.
Consider, as an example, 5+7:
5 = 101 (Base 2)
7 = 111 (Base 2)
Now consider adding the two (base 2) digits:
0+0 = 0 = 0 carry 0
1+0 = 1 = 1 carry 0
0+1 = 1 = 1 carry 0
1+1 = 10 = 0 carry 1
The sum (without carrying) of A+B is A^B and the carry is A&B; and when you carry a number it is shifted one digit to the left (hence (A&B)<<1).
So:
5 = 101 (Base 2)
7 = 111 (Base 2)
5^7 = 010 (sum without carrying)
5&7 = 101 (the carry shifted left)
Then we can recurse to add the carry:
A = 010
B = 1010
A^B = 1000 (sum without carrying)
A&B = 0010 (the carry shifted left)
Then we can recurse again as we still have more to carry:
A' = 1000
B' = 100 (without the leading zeros)
A'^B' = 1100 (sum without carrying)
A'&B' = 0000 (the carry shifted left)
Now there is nothing to carry - so we can stop and the answer is 1100 (base 2) = 12 (base 10).
The algorithm is just implementing decimal addition as (longhand) binary addition using the ors to add and the bitshifted ands to find the carry and will recurse until there is nothing more to carry (which will always occur as the bitshift appends another zero to the carry each time so with each recursion at least one more bit will not generate a carry value each time).
We are adding converting the integers to bits and using bitwise operators .
EXOR i.e ^ : 0 ^0 and 1 ^1 =0 , other cases give 1.
AND i.e & 1^1 =1 , ..other cases give 0.
<< or left shift . i.e shift left and append a 0 bit : 0010 becomes 0100
eg.
add(2,3)
2= 0010
3=0011
exor both : to get initial sum : 0001
carry : a &b = 0010
Left shift by 1 bit : 0100 i.e 4
add(1,4)
exor both : 0001 0100 and u get 0101 i.e 5
carry = 0000 <<1 i.e 0000 ..
since carry is 0 , it stops addition and returns previous sum
This is the table for addition:
+ 0 1
-- --
0 | 0 1
1 | 1 10
▲
If you ignore the carry bit ▲ you'll see that it's the same as the XOR table:
^ 0 1
-- --
0 | 0 1
1 | 1 0
So if you combine two numbers with bitwise XOR you get bit-by-bit addition without carry.
Now, what is the carry? It's a bit that's only there when both inputs are 1.
You can get that with AND:
& 0 1
-- --
0 | 0 0
1 | 0 1
But it needs to be added to the sum after being shifted one position to the left, because it's "carried" over, hence the (a & b) << 1
So you can compute the addition without carry and the carry itself. How do you add them together without using addition? Simple! By recursing on this very definition of addition!
See #pbabcdefp's answer on why the recursion always terminates.

Understanding unsigned right shift

The JLS 15.19 describes the formula for >>> operator.
The value of n >>> s is n right-shifted s bit positions with
zero-extension, where:
If n is positive, then the result is the same as that of n >> s.
If n is negative and the type of the left-hand operand is int, then
the result is equal to that of the expression (n >> s) + (2 << ~s).
If n is negative and the type of the left-hand operand is long, then
the result is equal to that of the expression (n >> s) + (2L << ~s).
Why does n >>> s = (n >> s) + (2 << ~s), where ~s = 31 - s for int and ~s = 63 - s for long?
If n is negative it means that the sign bit is set.
>>> s means shift s places to the right introducing zeros into the vacated slots.
>> s means shift s places to the right introducing copies of the sign bit into the vacated slots.
E.g.
10111110000011111000001111100000 >>> 3 == 00010111110000011111000001111100
10111110000011111000001111100000 >> 3 == 11110111110000011111000001111100
Obviously if n is not negative, n >> s and n >>> s are the same. If n is negative, the difference will consist of s ones at the left followed by all zeros.
In other words:
(n >>> s) + X == n >> s (*)
where X consists of s ones followed by 32 - s zeros.
Because there are 32 - s zeros in X, the right-most one in X occurs in the position of the one in 1 << (32 - s), which is equal to 2 << (31 - s), which is the same as 2 << ~s (because ~s == -1 - s and shift amounts work modulo 32 for ints).
Now what happens when you add 2 << ~s to X? You get zero! Let's demonstrate this in the case s == 7. Notice that the the carry disappears off the left.
11111110000000000000000000000000
+ 00000010000000000000000000000000
________________________________
00000000000000000000000000000000
It follows that -X == 2 << ~s. Therefore adding -X to both sides of (*) we get
n >>> s == (n >> s) + (2 << ~s)
For long it's exactly the same, except that shift amounts are done modulo 64, because longs have 64 bits.
Here is some additional context that will help you understand pbabcdefp's answer if you don't already know the basics he assumes:
To understand bitwise operators you must think about numbers as strings of binary digits, eg. 20 = 00010100 and -4 = 11111100 (For the sake of clarity and not having to write so many digits I will be writing all binary numbers as bytes; ints are the same but four times as long). If you are unfamiliar with binary and binary operations, you can read more here. Note how the first digit is special: It makes numbers negative, as if it had a place value (remember elementary math, the ones/tens/hundreds places?) of the most negative number possible, so Byte.MIN_VALUE = -128 = 1000000, and setting any other bit to 1 always increases the number. To easily read a negative number such as 11110011, know that -1 = 11111111, then read the 0s as if they were 1s in a positive number, then that number is how far away you are from -1. So 11110011 = -1 - 00001100 = -1 - 12 = -13.
Also understand that ~s is bitwise NOT: It takes all the digits and flips them, this is actually equivalent to ~s = -1 - s. Eg ~5 (00000101) is -6 (11111010). Observe how my suggested method for reading negative binary numbers is simply a trick to be able to read the bitwise NOT of the number rather than the number itself, which is easier for negative numbers close to zero because those numbers have fewer 0s than 1s.

Change the least significant bit (LSB) in java

I am trying to change the LSB of a numerical value, say 50 which LSB is 0 because 50 % 2 is 0 (remainder operator) to a value of 1. Thus change the LSB from 0 to 1 in this case.
The code is below:
//Get the LSB from 50 using the modulas operator
lsb = 50 % 2;
//if the character equals 1
//and the least significant bit is 0, add 1
if(binaryValue == '1' && lsb ==0)
{
//This clearly does not work.
//How do I assign the altered LSB (1) to the value of 50?
50 = lsb + 1;
}
I am having problems inside the if statement, where I am tying to assign the altered LSB, which in this case is 1 to the value of 50. This is not the full code, thus all values are different.
Thanks
The xor operation ^ can be used to flip the value of a single bit. For example
int value = 4;
value = value ^ 1;
System.out.println(value);
Will output 5 since the least significant bit was changed to one.
XOR in java:
System.out.println(50 ^ 1);

Categories