What does ^= mean in Java? - java

I have seen the following code in HashMap.java.
h ^= k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
A few random inputs produced an output similar to addition, but following code resulted in 0
int p = 10;
p ^= 10;
System.out.println("_______ " + p);

The ^= operator does an XOR with the variable on the left and the operand, then does an assignment to that variable of the result.
XOR something with itself and you get zero. It is an efficient way to set a register to zero as it doesn't move any memory.

^ is known as XOR (Exclusive disjunction or exclusive or), a logical operator, which follows:
1 xor 1 = 0
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0
as p^=10 is equivalent to:
p = p ^ 10; or, p = p xor 10
with p = 10 your operation is simply: , (10 ^ 10), which will result in 0

^ is the symbol for a logical XOR (Exclusive OR).
When placed before an equals sign, this means 'XOR myself with the given value, and write the result back to myself'. a ^= value is the same as saying a = a ^ value.
It might make it clearer if done with other operators, such as add:
E.g:
int counter = 14;
// Add 20 to counter (could also be written counter = counter + 20):
counter += 20;
// Counter is now 34

It is a compound assignment operator in java:
x op= y is equivalent to x = x op y (loosely speaking, see above link).
For example:
x += y; is equivalent to x = x + y;
x -= y; is equivalent to x = x - y;
and so on ...
For reference, this is the complete list of all such operators in java:
+= -= *= /= &= |= ^= %= <<= >>= >>>=

^= is bitwise exclusive OR and assignment operator. x ^= 2 is same as x = x ^ 2.

Related

Undestanding of Capacity Calculation Algorithm in HashMap

I am interested to know the working of capacity calculation algorithm in HashMap.
where if we Create the Object HashMap with some required capacity 20 , then the algorithm will always calculate the next highest capacity i.e (2^x >20)
The below is the jdk implementation .....
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
can someone explain me how the above algorithm works , what happens at each step .
I have understood that at each step they are dividing the number 2 and doing bitwise Or to older value.
and this they are doing because they have to allocate the next (2^x) value greater than n,
But can someone please help in explaining me in each step what happens with some numbers, i tried to debug but feeling complicated.
I have some implementation in mind like below..
private static int calculateCapacity(int cap){
int max_capcity = 256;
if(cap<16){
return 16;
}else if(cap <32){
return 32;
}else if(cap <64){
return 64;
}else if(cap < 128){
return 128;
}
return max_capcity;
}
the above implementation can be used in stead of the complex bit wise and right shift one what is the significance of that.
This algorithm is a fast way to determine the smallest power of 2 which is larger than or equal to the given cap.
The way it works is it computes the number which has only one bit set, and this bit is at a position higher than all the other bits in your original number (or at the highest bit of the original number if it has only one bit set). To do so, it set all bits smaller than the leading bit to 1, and then adds 1.
Here is how it works for a positive number, written 001XXXXXXXXX (the bits after the leading bit do not matter):
int n = cap - 1; // will not change anything to the leading bit except
// if cap is already a power of 2. In that case,
// we had cap = 001000000000 and now n = 000111111111 and
// the other lines won't change anything, we just have to
// do +1 in the end and we're done, n = cap;
// otherwise, let's assume that not every 'X' is a '0'
n |= n >>> 1; // n >>> 1 = 0001XXXXXXX
// so n = 0011XXXXXXX
n |= n >>> 2; // n >>> 2 = 000011XXXXX
// so n = 001111XXXXX
n |= n >>> 4; // n = 0011111111X
n |= n >>> 8; // n = 00111111111
n |= n >>> 16; // n = 00111111111
return n + 1; // result = 01000000000
For negative numbers, n is negative at every line because the sign bit is always 1, so the result will be 1.

How does Xor work in swapping values?

Here is the original code:
public static String reverseString(String s){
if(s == null) return "";
char[] rev = s.toCharArray();
int i = 0, j = s.length() - 1;
while(i < j) {
rev[i] ^= rev[j];
rev[j] ^= rev[i];
rev[i++] ^= rev[j--];
}
return String.valueOf(rev);
}
My question is how does Xor work in swapping character values here, and why is rev[i++]^=rev[j--] needed here?
The code is equivalent to
rev[i] ^= rev[j];
rev[j] ^= rev[i];
rev[i] ^= rev[j];
i++; j--;
The last part is just needed to increment i and decrement j for the next loop iteration.
As to why x ^= y; y ^= x; x ^= y works to swap the values, I don't know why, but you can see that it works on 1-bit values by look at all four possibilities:
start after x^=y after y^=x after x^=y
x y x y x y x y
0 0 0 0 0 0 0 0
0 1 1 1 1 0 1 0
1 0 1 0 1 1 0 1
1 1 0 1 0 1 1 1
So you can see that in all cases, the x and y bits are swapped. When the statements are applied to larger integers, the ^ operator works on all bits in parallel, so the end result is that every pair of bits is swapped, i.e. the entire values are swapped.
XOR operator has this very unique operator that it acts as inequality detector meaning only when the two bits differ result will be 1 else result is 0.
Now take this for example say in A^B, ith bit 1, this means that ith bit of A and B differ. Meaning one of them is 1 and the other is 0.
Now when we do this (A^B)^B , if the ith bit in B was 0, what we will get is 1 since 1^0 = 1, which is equal to ith bit in A and (A^B)^A = 0, which is ith bit in B.
Similarly,When ith bit is B is 1 and in A is 0, again swapping occurs.
Same logic applies to when ith bit in A^B is 0. You can veryify it very easily.
Its easy to see how the swapping is occurring, When you xor the original number with A^B, you get the other number, because swapping happens for each of the respective bits
The below routine is expected to swap the values of a and b
a = a ^ b
b = b ^ a
a = a ^ b
Let's analyze to see how and why the swap works.
For that, let's not swap the values, but store them in separate variables, so we can see what exactly goes on.
a0 = a ^ b
b1 = b ^ a0
a1 = a0 ^ b1
Simplifying the equations using below properties of XOR. Check XOR Properties#Wikipedia for reference
commutative (a ^ b == b ^ a)
associative (a ^ (b ^ c) == (a ^ b) ^ c)
a ^ a == 0
0 ^ a == a
a0 = a ^ b // Equation #1
b1 = b ^ a0
a1 = a0 ^ b1
b1 = b ^ a0 // Equation #2
= b ^ (a ^ b) // Using Equation #1
= b ^ (b ^ a) // Property #1
= (b ^ b) ^ a // Property #2
= 0 ^ a // Property #3
= a // Property #4
a1 = a0 ^ b1
= a0 ^ (b ^ a0) // Using Equation #2
= (a ^ b) ^ (b ^ (a ^ b)) // Using Equation #1
= (b ^ a) ^ (b ^ (b ^ a)) // Using Property #1
= (b ^ a) ^ ((b ^ b) ^ a) // Using Property #2
= (b ^ a) ^ (0 ^ a) // Using Property #3
= (b ^ a) ^ a // Using Property #4
= b ^ (a ^ a) // Using Property #2
= b ^ 0 // Using Property #3
= b // Using Property #4
As you can see, b1 now contains the original value of a and a1 contains the original value of b, i.e. the values of b and a are swapped
In summary, a^=b;b^=a;a^=b is just an idiomatic expression, nothing magical in it :)
Plain English explanation for the same
XOR sets the bits when the operand bits are dissimilar and resets the bits otherwise
Let's walk through the transformations that take place with an example. For that let's say, we have the following numbers (in binary) assigned to the variables.
a = 1 1 0 0
b = 1 0 1 0
Step #1: a = a ^ b // CREATE A MASK
a = 0 1 1 0
b = 1 0 1 0
Imagine the new value of a is a mask for generating the old value of a given b or generating the old value of b given a.
Step #2: b = b ^ a // Recover original value of a using mask and original value of b
a = 0 1 1 0
b = 1 1 0 0
Since b is still preserved/untouched, we can recover original value of a with the mask - which is what we did in this step
Step #3: a = a ^ b // Recover original value of b using mask and original value of a
a = 1 0 1 0
b = 1 1 0 0
Now we have the original value of a in variable b, so we can use our same mask to recover the original value of b. We can overwrite the mask now, since we don't need the mask after this step.
If you will agree that y == (x^y)^x == x^(y^x), then you have the answer.
Consider an abstract version of the loop body in the code you gave:
a = a ^ b
b = b ^ a
a = a ^ b
Now rename one value to clarify what's happening:
a_xor_b = a ^ b
b = b ^ a_xor_b // Now b is the original a because b^(a^b) == a!
a = a_xor_b ^ b // Now a is the original b because (a^b)^a == b!
Now note the code works fine if a_xor_b is the same variable is a.
It may be easier to first consider a different (but closely related) way of swapping two number values a and b:
a = a + b;
b = a - b;
a = -b + a;
This works both with pure arbitrary-precision numbers, and with integers modulo N (integers that wrap around when they get too big or small, like they do in Java).
To analyze this mathematically, we should assign a new symbol each time a value would change so that = can represent mathematical equality instead of assignment. Then, it is just a matter of basic algebra.
a1 = a0 + b0
b2 = a1 - b0 = (a0 + b0) - b0 = a0
a2 = -b2 + a1 = -(a0) + (a0 + b0) = b0
What about XOR? One way to explain XOR is to think of it as binary addition without carrying. Performing a swap with XOR is then equivalent to performing the "addition swap" described above on each bit modulo 2. The expression can be simplified, though, since in addition modulo 2, each number is its own inverse (equivalently, addition and subtraction are the same). This (with commutativity) gives us the familiar:
a = a ^ b;
b = b ^ a;
a = a ^ b;
In general, the "addition swap" above can be performed in any mathematical group (even if it is non-commutative -- basically just associativity and inverses are needed). Another way of thinking of XOR is just that it induces a group structure on the n-bit integers, and so swapping works just as it does in any group.

how many arithmetic operation can be made at right side of a variable

for(int i = 1; i <= 5; i++) {
for(int j = 1; j <= i; j++) {
int a = i + j*2;
System.out.print(a);
}
}
when run the above code I am getting output as
3
46
579
681012
79111315
I am not able to understand why it is printing first row as 3, i+j*2 =4 as per the logic.
I am not able to understand why it is printing first row as 3, i+j*2 =4 as per the logic.
Precedence. Multiplication takes precedence over addition, so on the first call, i+j*2 is 1+1*2 which is 1+(1*2) which is 1+2 which is 3.
The precedence of basic operations can be remembered with PEMDAS or BODMAS (the "MD" and "AS" have the same precedence, so I've shown them on a single line here):
P Parentheses / Brackets B
E Exponenentiation / Orders1 O
MD Multiplication & Division DM
AS Addition and Subtraction AS
1 Powers (2^5), square roots, etc.
The Java site has a page on operator precedence, which has this table:
postfix expr++ expr--
unary ++expr --expr +expr -expr ~ !
multiplicative * / %
additive + -
shift << >> >>>
relational < > <= >= instanceof
equality == !=
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
ternary1 ? :
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=
1 They mean the conditional operator, which is a ternary operator (an operator accepting three operands) and as it happens, the only one Java has.
Multiplication (*) has arithmetic precedence over addition (+). In the first iteration, i and j are both 1. The first thing to be calculated is j*2, i.e., 1*2=2. Then we add i and the previously calculated product and get 1+2=3.

Bitwise operator for simply flipping all bits in an integer?

I have to flip all bits in a binary representation of an integer. Given:
10101
The output should be
01010
What is the bitwise operator to accomplish this when used with an integer? For example, if I were writing a method like int flipBits(int n);, what would go in the body? I need to flip only what's already present in the number, not all 32 bits in the integer.
The ~ unary operator is bitwise negation. If you need fewer bits than what fits in an int then you'll need to mask it with & after the fact.
Simply use the bitwise not operator ~.
int flipBits(int n) {
return ~n;
}
To use the k least significant bits, convert it to the right mask.
(I assume you want at least 1 bit of course, that's why mask starts at 1)
int flipBits(int n, int k) {
int mask = 1;
for (int i = 1; i < k; ++i)
mask |= mask << 1;
return ~n & mask;
}
As suggested by Lưu Vĩnh Phúc, one can create the mask as (1 << k) - 1 instead of using a loop.
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return ~n & mask;
}
There is a number of ways to flip all the bit using operations
x = ~x; // has been mentioned and the most obvious solution.
x = -x - 1; or x = -1 * (x + 1);
x ^= -1; or x = x ^ ~0;
Well since so far there's only one solution that gives the "correct" result and that's.. really not a nice solution (using a string to count leading zeros? that'll haunt me in my dreams ;) )
So here we go with a nice clean solution that should work - haven't tested it thorough though, but you get the gist. Really, java not having an unsigned type is extremely annoying for this kind of problems, but it should be quite efficient nonetheless (and if I may say so MUCH more elegant than creating a string out of the number)
private static int invert(int x) {
if (x == 0) return 0; // edge case; otherwise returns -1 here
int nlz = nlz(x);
return ~x & (0xFFFFFFFF >>> nlz);
}
private static int nlz(int x) {
// Replace with whatever number leading zero algorithm you want - I can think
// of a whole list and this one here isn't that great (large immediates)
if (x < 0) return 0;
if (x == 0) return 32;
int n = 0;
if ((x & 0xFFFF0000) == 0) {
n += 16;
x <<= 16;
}
if ((x & 0xFF000000) == 0) {
n += 8;
x <<= 8;
}
if ((x & 0xF0000000) == 0) {
n += 4;
x <<= 4;
}
if ((x & 0xC0000000) == 0) {
n += 2;
x <<= 2;
}
if ((x & 0x80000000) == 0) {
n++;
}
return n;
}
faster and simpler solution :
/* inverts all bits of n, with a binary length of the return equal to the length of n
k is the number of bits in n, eg k=(int)Math.floor(Math.log(n)/Math.log(2))+1
if n is a BigInteger : k= n.bitLength();
*/
int flipBits2(int n, int k) {
int mask = (1 << k) - 1;
return n ^ mask;
}
One Line Solution
int flippingBits(int n) {
return n ^ ((1 << 31) - 1);
}
I'd have to see some examples to be sure, but you may be getting unexpected values because of two's complement arithmetic. If the number has leading zeros (as it would in the case of 26), the ~ operator would flip these to make them leading ones - resulting in a negative number.
One possible workaround would be to use the Integer class:
int flipBits(int n){
String bitString = Integer.toBinaryString(n);
int i = 0;
while (bitString.charAt(i) != '1'){
i++;
}
bitString = bitString.substring(i, bitString.length());
for(i = 0; i < bitString.length(); i++){
if (bitString.charAt(i) == '0')
bitString.charAt(i) = '1';
else
bitString.charAt(i) = '0';
}
int result = 0, factor = 1;
for (int j = bitString.length()-1; j > -1; j--){
result += factor * bitString.charAt(j);
factor *= 2;
}
return result;
}
I don't have a java environment set up right now to test it on, but that's the general idea. Basically just convert the number to a string, cut off the leading zeros, flip the bits, and convert it back to a number. The Integer class may even have some way to parse a string into a binary number. I don't know if that's how the problem needs to be done, and it probably isn't the most efficient way to do it, but it would produce the correct result.
Edit: polygenlubricants' answer to this question may also be helpful
I have another way to solve this case,
public static int complementIt(int c){
return c ^ (int)(Math.pow(2, Math.ceil(Math.log(c)/Math.log(2))) -1);
}
It is using XOR to get the complement bit, to complement it we need to XOR the data with 1, for example :
101 XOR 111 = 010
(111 is the 'key', it generated by searching the 'n' square root of the data)
if you are using ~ (complement) the result will depend on its variable type, if you are using int then it will be process as 32bit.
As we are only required to flip the minimum bits required for the integer (say 50 is 110010 and when inverted, it becomes 001101 which is 13), we can invert individual bits one at a time from the LSB to MSB, and keep shifting the bits to the right and accordingly apply the power of 2. The code below does the required job:
int invertBits (int n) {
int pow2=1, int bit=0;
int newnum=0;
while(n>0) {
bit = (n & 1);
if(bit==0)
newnum+= pow2;
n=n>>1;
pow2*=2;
}
return newnum;
}
import java.math.BigInteger;
import java.util.Scanner;
public class CodeRace1 {
public static void main(String[] s) {
long input;
BigInteger num,bits = new BigInteger("4294967295");
Scanner sc = new Scanner(System.in);
input = sc.nextInt();
sc.nextLine();
while (input-- > 0) {
num = new BigInteger(sc.nextLine().trim());
System.out.println(num.xor(bits));
}
}
}
The implementation from openJDK, Integer.reverse():
public static int More ...reverse(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
Base on my experiments on my laptop, the implementation below was faster:
public static int reverse2(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i & 0x00ff00ff) << 8 | (i >>> 8) & 0x00ff00ff;
i = (i & 0x0000ffff) << 16 | (i >>> 16) & 0x0000ffff;
return i;
}
Not sure what's the reason behind it - as it may depends on how the java code is interpreted into machine code...
If you just want to flip the bits which are "used" in the integer, try this:
public int flipBits(int n) {
int mask = (Integer.highestOneBit(n) << 1) - 1;
return n ^ mask;
}
public static int findComplement(int num) {
return (~num & (Integer.highestOneBit(num) - 1));
}
int findComplement(int num) {
int i = 0, ans = 0;
while(num) {
if(not (num & 1)) {
ans += (1 << i);
}
i += 1;
num >>= 1;
}
return ans;
}
Binary 10101 == Decimal 21
Flipped Binary 01010 == Decimal 10
One liner (in Javascript - You could convert to your favorite programming language )
10 == ~21 & (1 << (Math.floor(Math.log2(21))+1)) - 1
Explanation:
10 == ~21 & mask
mask : For filtering out all the leading bits before the significant bits count (nBits - see below)
How to calculate the significant bit counts ?
Math.floor(Math.log2(21))+1 => Returns how many significant bits are there (nBits)
Ex:
0000000001 returns 1
0001000001 returns 7
0000010101 returns 5
(1 << nBits) - 1 => 1111111111.....nBits times = mask
It can be done by a simple way, just simply subtract the number from the value
obtained when all the bits are equal to 1 .
For example:
Number: Given Number
Value : A number with all bits set in a given number.
Flipped number = Value – Number.
Example :
Number = 23,
Binary form: 10111
After flipping digits number will be: 01000
Value: 11111 = 31
We can find the most significant set bit in O(1) time for a fixed size integer. For
example below code is for a 32-bit integer.
int setBitNumber(int n)
{
n |= n>>1;
n |= n>>2;
n |= n>>4;
n |= n>>8;
n |= n>>16;
n = n + 1;
return (n >> 1);
}

Swap in array, sorting proramm [duplicate]

This question already exists:
Wtat does it mean "^=" [duplicate]
Closed 7 years ago.
I have this peace of code in wiki page about sorting.
I suppose it has to swap to array elements, but can somebody explain it properly
array[i] ^= array[i-1];
array[i-1] ^= array[i];
array[i] ^= array[i-1];
wiki page https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D1%88%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%D0%BC
That is a way of swapping array[i] and array[i-1].
^= does a bitwise XOR between the two arguments and assigns it to the left one.
To see how that causes a swap lets consider just a pair of bits : A and B which contain values x and y respectively .
Before starting we have :
A = x
B = y
First instruction A^=B means A = ( A XOR B ) So we end up with :
A = x XOR y
B = y
Second instruction B^=A means B = ( B XOR A) So we end up with :
A = x XOR y
B = y XOR ( x XOR y )
Third instruction A^=B means A = ( A XOR B) So we end up with :
A = (x XOR y ) XOR ( y XOR ( x XOR y ) )
B = y XOR ( x XOR y )
Making use of the associativity and conmutativity of XOR we can reorder the previous operations as :
A = (x XOR x) XOR (y XOR y) XOR y
B = (y XOR y) XOR x
Making use of the property that a bit XOR itself is always 0 :
A = 0 XOR 0 XOR y
B = 0 XOR x
Making use the property that 0 XOR a bit is always the same bit :
A = y
B = x
As you can see A and B have been swapped.

Categories

Resources