java understanding bitwise manipulation - java

Recently I have been learning about bitwise operators and along the way there is this code that finds the binary digits of a decimal number using the AND(&) bitwise operator, the code is as follows:
byte b = -34;
for(int t = 128;t > 0; t = t/2)
{
if((b & t) != 0)System.out.println("1 ");
else System.out.println("0 ");
System.out.println("b & t yields: " + (b & t));
}
I have modified the code to show the value calculated by b&t during each iteration. I would like to understand the exact mechanism behind this code as to why it works to find the binary digits, please explain why is b compared to t each iteration and why is t divided by 2 each iteration?
In addition, I would like to know how is (b&t) calculated manually by listing the binary digits.I do have an understanding how & works but when I listed out the binary digits of 34 and 128 and compared them:
1 0 0 0 0 0 0 0(128)
0 0 1 0 0 0 1 0(34) //I am unsure if the negative sign should be included
---------------
0 0 0 0 0 0 0 0
the result I got was 0, however the program returns 128 which is perplexing.
Below I will also include the result of the execution of the program:
1
b & t yields: 128
1
b & t yields: 64
0
b & t yields: 0
1
b & t yields: 16
1
b & t yields: 8
1
b & t yields: 4
1
b & t yields: 2
0
b & t yields: 0
Much obliged for the help :)

Dividing t by 2 is a bit-shift to the right:
1 0 0 0 0 0 0 0 128 = t
0 1 0 0 0 0 0 0 64 = t / 2
0 0 1 0 0 0 0 0 32 = t / 2 / 2
...
t always has one bit set to 1, all others are 0.
Then you compare that to b using &. Each result bit is 1 if and only if the corresponding bit in both inputs is 1 as well.
That means that we basically check if the bit in b is 1 at the location that the t-bit is 1. That is done for all bits from left to right.

Since there were two questions:
(1) OP is perplex why his hand-calculation does not match with program's code and
(2) OP would like to know why one of the variables is divided by 2.
I merely combine the answers:
(1) Negative numbers are represented as two's complement. Therefore negative 34 is
0 0 1 0 0 0 1 0 <-- +34
1 1 0 1 1 1 0 1 <-- one's complement of 34
1 1 0 1 1 1 1 0 <-- two's complement of 34
Note: two's complement is one's complement + 1.
(2) Division by 2 is shifting to the right (if it is binary). That's why, the third time in the loop, it outputs zero (The only 1 in 128 is 'AND'ed with the third zero in -34).

Related

What does "bits 6-0" or "bits 10-6 " mean in the javadoc of DataInput?

When reading the javadoc of DataInput specifically in the "Modified UTF-8" section. I come across three tables that say "0 bits 6-0" ,"1 1 0 bits 10-6",...,"1 0 bits 5-0".
I'm a Java newbie so to me it looks like subtractions, not sure, but if that's the case and we add it to the ones and zeros it would make 7 bits.
As far as I know, a byte is made up of 8 bits.
What does these "0 bits 6-0..." mean?
The javadoc is telling you how each byte is divided.
Consider each byte as a vector of 8 individual elements (bits).
The first block has only one byte, and the corresponding possible bit values.
byte 1
bit number 7 6 5 4 3 2 1 0
bit value 0 ? ? ? ? ? ? ? <-- bits 6 - 0
This means that for characters encoded in one byte, the leading bit will always be 0. These are the characters from \u0001 to \u007F.
The second block has two bytes and gets a bit more complicated
byte 1 byte 2
bit number 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
bit value 1 1 0 ? ? ? ? ? | 1 0 ? ? ? ? ? ?
^ ^
| |
bits 10 to 6 of bits 5 to 0 of
the utf-8 codepoint the utf-8 codepoint
These are the characters in the range from \u0080 to \u07FF
So for example, a symbol in this range is µ (micro sign).
In normal unicode the bytes are 11000010 10110101
Take a look at this character and see how it lines up with the bits for two-byte chars. You have
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 0 0 0 0 1 0 1 0 1 1 0 1 0 1
Bits 10-6 ------*-*-*----*-* ^-^-^-^-^-^----bits 5-0
You end up with
byte 1 byte 2
bit number 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
bit value 1 1 0 - - 0 1 0 | 1 0 1 1 0 1 0 1
Where bytes 11 and 12 would be 0 but I put a - in there just to show their (in)significance.
Sorry for the ascii art, I hope it helps.
It shows ranges of bits. Bits are numbered, the lowest, least significant bit has index 0, the next bit has index 1, the next bit has index 2 etc. For example, number 13 has binary representation 1101. It means that bit number 0 has value 1, bit number 1 has value 0, and bits number 2 and 3 have value of 1. So, for example, in the documentation "0 bits 6-0" means that the highest bit in the byte must be zero, while seven lower bits with the indexes from 6 to 0 are occupied by your number.
That table is talking about how characters is represented in the modified UTF8 encoding. I'll use this part as an example:
The null character '\u0000' and characters in the range '\u0080' to '\u07FF' are represented by a pair of bytes.
Notice that you can use 11 bits to represent those numbers. The largest number you can represent with 11 bits is 2^11 - 1 = 2047 = 7FF in hex. Let's number those 11 bits 0 to 10, so bit-10 is the most significant bit, and bit-0 is the least significant.
The table is telling you that in the modified UTF8 encoding, the characters that those numbers are encoded by are instead represented by 2 bytes.
The first byte starts with the bits 110 (these three bits are fixed), followed by bit-10, bit-9, bit-8, bit-7, bit-6 of the number we are trying to represent.
The second byte starts with the bits 10 (these two bits are fixed), followed by bit-5, bit-4, bit-3, bit-2, bit-1, bit-0 of the number.
In short, "bits 10-6" means "bits 10 to 6", which is not 4, but 5 bits.
I encourage you to compare this with the normal UTF8 encoding to see where the difference is.

How do I represent potency in Java with all zeros? [duplicate]

What function does the ^ (caret) operator serve in Java?
When I try this:
int a = 5^n;
...it gives me:
for n = 5, returns 0
for n = 4, returns 1
for n = 6, returns 3
...so I guess it doesn't perform exponentiation. But what is it then?
The ^ operator in Java
^ in Java is the exclusive-or ("xor") operator.
Let's take 5^6 as example:
(decimal) (binary)
5 = 101
6 = 110
------------------ xor
3 = 011
This the truth table for bitwise (JLS 15.22.1) and logical (JLS 15.22.2) xor:
^ | 0 1 ^ | F T
--+----- --+-----
0 | 0 1 F | F T
1 | 1 0 T | T F
More simply, you can also think of xor as "this or that, but not both!".
See also
Wikipedia: exclusive-or
Exponentiation in Java
As for integer exponentiation, unfortunately Java does not have such an operator. You can use double Math.pow(double, double) (casting the result to int if necessary).
You can also use the traditional bit-shifting trick to compute some powers of two. That is, (1L << k) is two to the k-th power for k=0..63.
See also
Wikipedia: Arithmetic shift
Merge note: this answer was merged from another question where the intention was to use exponentiation to convert a string "8675309" to int without using Integer.parseInt as a programming exercise (^ denotes exponentiation from now on). The OP's intention was to compute 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0 = 8675309; the next part of this answer addresses that exponentiation is not necessary for this task.
Horner's scheme
Addressing your specific need, you actually don't need to compute various powers of 10. You can use what is called the Horner's scheme, which is not only simple but also efficient.
Since you're doing this as a personal exercise, I won't give the Java code, but here's the main idea:
8675309 = 8*10^6 + 6*10^5 + 7*10^4 + 5*10^3 + 3*10^2 + 0*10^1 + 9*10^0
= (((((8*10 + 6)*10 + 7)*10 + 5)*10 + 3)*10 + 0)*10 + 9
It may look complicated at first, but it really isn't. You basically read the digits left to right, and you multiply your result so far by 10 before adding the next digit.
In table form:
step result digit result*10+digit
1 init=0 8 8
2 8 6 86
3 86 7 867
4 867 5 8675
5 8675 3 86753
6 86753 0 867530
7 867530 9 8675309=final
As many people have already pointed out, it's the XOR operator. Many people have also already pointed out that if you want exponentiation then you need to use Math.pow.
But I think it's also useful to note that ^ is just one of a family of operators that are collectively known as bitwise operators:
Operator Name Example Result Description
a & b and 3 & 5 1 1 if both bits are 1.
a | b or 3 | 5 7 1 if either bit is 1.
a ^ b xor 3 ^ 5 6 1 if both bits are different.
~a not ~3 -4 Inverts the bits.
n << p left shift 3 << 2 12 Shifts the bits of n left p positions. Zero bits are shifted into the low-order positions.
n >> p right shift 5 >> 2 1 Shifts the bits of n right p positions. If n is a 2's complement signed number, the sign bit is shifted into the high-order positions.
n >>> p right shift -4 >>> 28 15 Shifts the bits of n right p positions. Zeros are shifted into the high-order positions.
From here.
These operators can come in handy when you need to read and write to integers where the individual bits should be interpreted as flags, or when a specific range of bits in an integer have a special meaning and you want to extract only those. You can do a lot of every day programming without ever needing to use these operators, but if you ever have to work with data at the bit level, a good knowledge of these operators is invaluable.
It's bitwise XOR, Java does not have an exponentiation operator, you would have to use Math.pow() instead.
XOR operator rule =>
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
Binary representation of 4, 5 and 6 :
4 = 1 0 0
5 = 1 0 1
6 = 1 1 0
now, perform XOR operation on 5 and 4:
5 ^ 4 => 1 0 1 (5)
1 0 0 (4)
----------
0 0 1 => 1
Similarly,
5 ^ 5 => 1 0 1 (5)
1 0 1 (5)
------------
0 0 0 => (0)
5 ^ 6 => 1 0 1 (5)
1 1 0 (6)
-----------
0 1 1 => 3
It is the XOR bitwise operator.
Lot many people have already explained about what it is and how it can be used but apart from the obvious you can use this operator to do a lot of programming tricks like
XORing of all the elements in a boolean array would tell you if the array has odd number of true elements
If you have an array with all numbers repeating even number of times except one which repeats odd number of times you can find that by XORing all elements.
Swapping values without using temporary variable
Finding missing number in the range 1 to n
Basic validation of data sent over the network.
Lot many such tricks can be done using bit wise operators, interesting topic to explore.
XOR operator rule
0 ^ 0 = 0
1 ^ 1 = 0
0 ^ 1 = 1
1 ^ 0 = 1
Bitwise operator works on bits and performs bit-by-bit operation. Assume if a = 60 and b = 13; now in binary format they will be as follows −
a = 0011 1100
b = 0000 1101
a^b ==> 0011 1100 (a)
0000 1101 (b)
------------- XOR
0011 0001 => 49
(a ^ b) will give 49 which is 0011 0001
As others have said, it's bitwise XOR. If you want to raise a number to a given power, use Math.pow(a , b), where a is a number and b is the power.
AraK's link points to the definition of exclusive-or, which explains how this function works for two boolean values.
The missing piece of information is how this applies to two integers (or integer-type values). Bitwise exclusive-or is applied to pairs of corresponding binary digits in two numbers, and the results are re-assembled into an integer result.
To use your example:
The binary representation of 5 is 0101.
The binary representation of 4 is 0100.
A simple way to define bitwise XOR is to say the result has a 1 in every place where the two input numbers differ.
With 4 and 5, the only difference is in the last place; so
0101 ^ 0100 = 0001 (5 ^ 4 = 1) .
It is the Bitwise xor operator in java which results 1 for different value of bit (ie 1 ^ 0 = 1) and 0 for same value of bit (ie 0 ^ 0 = 0) when a number is written in binary form.
ex :-
To use your example:
The binary representation of 5 is 0101.
The binary representation of 4 is 0100.
A simple way to define Bitwise XOR is to say the result has a 1 in every place where the two input numbers differ.
0101 ^ 0100 = 0001 (5 ^ 4 = 1) .
To perform exponentiation, you can use Math.pow instead:
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Math.html#pow%28double,%20double%29
As already stated by the other answer(s), it's the "exclusive or" (XOR) operator. For more information on bit-operators in Java, see: http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html
That is because you are using the xor operator.
In java, or just about any other language, ^ is bitwise xor,
so of course,
10 ^ 1 = 11.
more info about bitwise operators
It's interesting how Java and C# don't have a power operator.
It is the bitwise xor operator in java which results 1 for different value (ie 1 ^ 0 = 1) and 0 for same value (ie 0 ^ 0 = 0).
^ is binary (as in base-2) xor, not exponentiation (which is not available as a Java operator). For exponentiation, see java.lang.Math.pow().
It is XOR operator. It is use to do bit operations on numbers. It has the behavior such that when you do a xor operation on same bits say 0 XOR 0 / 1 XOR 1 the result is 0. But if any of the bits is different then result is 1.
So when you did 5^3 then you can look at these numbers 5, 6 in their binary forms and thus the expression becomes (101) XOR (110) which gives the result (011) whose decimal representation is 3.
As an addition to the other answers, it's worth mentioning that the caret operator can also be used with boolean operands, and it returns true (if and only if) the operands are different:
System.out.println(true ^ true); // false
System.out.println(true ^ false); // true
System.out.println(false ^ false); // false
System.out.println(false ^ true); // true
^ = (bitwise XOR)
Description
Binary XOR Operator copies the bit if it is set in one operand but not both.
example
(A ^ B) will give 49 which is 0011 0001
In other languages like Python you can do 10**2=100, try it.

Java: How should I create a binary tree given binary codes

Say I have 2 leaves {1,2} and I was given their binary codes (same length), meaning that I should construct the binary tree based on the binary codes. And after constructing the binary tree, if I traverse the tree, I should retrieve the same binary codes for leave 1 and 2.
The data format is as follow:
leave : binary code
1: 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 1 1 0 1 0 1 1 0 1
2: 0 1 0 0 0 1 0 0 0 1 0 1 1 1 1 1 1 0 1 0 0 1 0 1
For example, when the binary code is 0 1 1 0, I start from the root of the tree and I go left when I see 0 and right when I see 1 ...
Question: How can I construct a binary tree based on the binary code given ? (Please note that I am in fact dealing with 200000 leaves , and hence 200000 lines of binary code. So I need an efficient method to do this.)
You may want to look at this
http://www.cs.princeton.edu/courses/archive/spring01/cs126/assignments/prefix.html
this should hopefully give you insight on what you need to do to create the tree you want

Iterative Reduction to Null Matrix

Here's the problem: I'm given a matrix like
Input:
1 1 1
1 1 1
1 1 1
At each step, I need to find a "second" matrix of 1's and 0's with no two 1's on the same row or column. Then, I'll subtract the second matrix from the original matrix. I will repeat the process until I get a matrix with all 0's. Furthermore, I need to take the least possible number of steps.
I need to print all the "second" matrices in O(n) time. In the above example I can get to the null matrix in 3 steps by subtracting these three matrices in order:
Expected output:
1 0 0
0 1 0
0 0 1
0 0 1
1 0 0
0 1 0
0 1 0
0 0 1
1 0 0
I have coded an attempt, in which I am finding the first maximum value and creating the second matrices based on the index of that value. But for the above input I am getting 4 output matrices, which is wrong:
My output:
1 0 0
0 1 0
0 0 1
0 1 0
1 0 0
0 0 0
0 0 1
0 0 0
1 0 0
0 0 0
0 0 1
0 1 0
My solution works for most of the test cases but fails for the one given above. Can someone give me some pointers on how to proceed, or find an algorithm that guarantees optimality?
Test case that works:
Input:
0 2 1
0 0 0
3 0 0
Output
0 1 0
0 0 0
1 0 0
0 1 0
0 0 0
1 0 0
0 0 1
0 0 0
1 0 0
Summing of each row / column and taking the largest of those sums gives you the optimal number of matrix subtractions required to reduce to a null matrix.
For example:
1 2 4 0 = 7
2 2 0 1 = 5
0 0 1 0 = 1
3 0 2 1 = 6
= = = =
6 4 7 2
Which means that this matrix will take 7 optimal subtractions to empty.
I believe that counting backwards from this and removing from columns / row with that value will solve your problem (I am not sure of an efficient way of selecting these - brute force?).
You can also use your previous method to remove extra elements.
For example (using the above matrix).
Step 7:
We must subtract from row 1 & column 3.
0 0 1 0
0 0 0 0
0 0 0 0
0 0 0 0
Solves this, so now we can use your previous method to remove "bonus" elements.
0 0 1 0
1 0 0 0
0 0 0 0
0 0 0 1
Now apply the sum of each row / column again and continue for the next step.
Step 6:
1 2 3 0 = 6
1 2 0 1 = 4
0 0 1 0 = 1
3 0 2 0 = 5
= = = =
5 4 6 1
Next subtraction:
0 0 1 0
0 1 0 0
0 0 0 0
1 0 0 0
And so on.
Note: This still does not work very well with "all 1" matrices, as you get stuck on the problem of selecting 1 from every row and column (same as you did in your example).
But someone may be able to extend my solution.
Let Number of rows = Number of columns = N
for iteration=1:N
for row=1:N
cell(row,(row+iteration)%N) := 0
Number of iterations is N. In every iteration N one's will be changed to 0
I'm not entirely sure if this is what you are after, but could you create a list of available columns and mark them as used for each iteration.
For Example:
repeat until an empty matrix
mark all columns as available
for each row
find the maximum value in all available columns and store it's coordinates
mark that column as unavailable
print, decrement and clear the list of stored coordinates
This doesn't work, but it does show the algorithm that user1459032 is using.
1) If all you want to do is iterate through all the elements in your matrix...
2) then all you have to do is loop for (int i=0; i < rows*cols; i++) {} ...
3) And such a loop is ALREADY O(n) (i.e. it increases LINEARLY with the #/elements in your matrix)
I'm pretty sure that this is some kind of variant of the exact cover problem, which is known to be NP-complete. Your proposed algorithm is a simple greedy solution. The problem with greedy solutions is that they often work well enough to convince you that greed is good and then suddenly leave you high and dry looking for a better solution. (Consider the global economy, for example.) Anyway, Knuth's Dancing Links technique is a standard way of solving the problem (exact set cover, not global economy).

Why if (n & -n) == n then n is a power of 2?

Line 294 of java.util.Random source says
if ((n & -n) == n) // i.e., n is a power of 2
// rest of the code
Why is this?
Because in 2's complement, -n is ~n+1.
If n is a power of 2, then it only has one bit set. So ~n has all the bits set except that one. Add 1, and you set the special bit again, ensuring that n & (that thing) is equal to n.
The converse is also true because 0 and negative numbers were ruled out by the previous line in that Java source. If n has more than one bit set, then one of those is the highest such bit. This bit will not be set by the +1 because there's a lower clear bit to "absorb" it:
n: 00001001000
~n: 11110110111
-n: 11110111000 // the first 0 bit "absorbed" the +1
^
|
(n & -n) fails to equal n at this bit.
The description is not entirely accurate because (0 & -0) == 0 but 0 is not a power of two. A better way to say it is
((n & -n) == n) when n is a power of two, or the negative of a power of two, or zero.
If n is a power of two, then n in binary is a single 1 followed by zeros.
-n in two's complement is the inverse + 1 so the bits lines up thus
n 0000100...000
-n 1111100...000
n & -n 0000100...000
To see why this work, consider two's complement as inverse + 1, -n == ~n + 1
n 0000100...000
inverse n 1111011...111
+ 1
two's comp 1111100...000
since you carry the one all the way through when adding one to get the two's complement.
If n were anything other than a power of two† then the result would be missing a bit because the two's complement would not have the highest bit set due to that carry.
† - or zero or a negative of a power of two ... as explained at the top.
You need to look at the values as bitmaps to see why this is true:
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
So only if both fields are 1 will a 1 come out.
Now -n does a 2's complement. It changes all the 0 to 1 and it adds 1.
7 = 00000111
-1 = NEG(7) + 1 = 11111000 + 1 = 11111001
However
8 = 00001000
-8 = 11110111 + 1 = 11111000
00001000 (8)
11111000 (-8)
--------- &
00001000 = 8.
Only for powers of 2 will (n & -n) be n.
This is because a power of 2 is represented as a single set bit in a long sea of zero's.
The negation will yield the exact opposite, a single zero (in the spot where the 1 used to be) in a sea of 1's. Adding 1 will shift the lower ones into the space where the zero is.
And The bitwise and (&) will filter out the 1 again.
In two's complement representation, the unique thing about powers of two, is that they consist of all 0 bits, except for the kth bit, where n = 2^k:
base 2 base 10
000001 = 1
000010 = 2
000100 = 4
...
To get a negative value in two's complement, you flip all the bits and add one. For powers of two, that means you get a bunch of 1s on the left up to and including the 1 bit that was in the positive value, and then a bunch of 0s on the right:
n base 2 ~n ~n+1 (-n) n&-n
1 000001 111110 111111 000001
2 000010 111101 111110 000010
4 000100 111011 111100 000100
8 001000 110111 111000 001000
You can easily see that the result of column 2 & 4 is going to be the same as column 2.
If you look at the other values missing from this chart, you can see why this doesn't hold for anything but the powers of two:
n base 2 ~n ~n+1 (-n) n&-n
1 000001 111110 111111 000001
2 000010 111101 111110 000010
3 000011 111100 111101 000001
4 000100 111011 111100 000100
5 000101 111010 111011 000001
6 000110 111001 111010 000010
7 000111 111000 111001 000001
8 001000 110111 111000 001000
n&-n will (for n > 0) only ever have 1 bit set, and that bit will be the least significant set bit in n. For all numbers that are powers of two, the least significant set bit is the only set bit. For all other numbers, there is more than one bit set, of which only the least significant will be set in the result.
It's property of powers of 2 and their two's complement.
For example, take 8:
8 = 0b00001000
-8 = 0b11111000
Calculating the two's complement:
Starting: 0b00001000
Flip bits: 0b11110111 (one's complement)
Add one: 0b11111000
AND 8 : 0b00001000
For powers of 2, only one bit will be set so adding will cause the nth bit of 2n to be set (the one keeps carrying to the nth bit). Then when you AND the two numbers, you get the original back.
For numbers that aren't powers of 2, other bits will not get flipped so the AND doesn't yield the original number.
Simply, if n is a power of 2 that means only one bit is set to 1 and the others are 0's:
00000...00001 = 2 ^ 0
00000...00010 = 2 ^ 1
00000...00100 = 2 ^ 2
00000...01000 = 2 ^ 3
00000...10000 = 2 ^ 4
and so on ...
and because -n is a 2's complement of n (that means the only bit which is 1 remains as it is and the bits on left side of that bit are sit to 1 which is actually doesn't matter since the result of AND operator & will be 0 if one of the two bits is zero):
000000...000010000...00000 <<< n
&
111111...111110000...00000 <<< -n
--------------------------
000000...000010000...00000 <<< n
Shown through example:
8 in hex = 0x000008
-8 in hex = 0xFFFFF8
8 & -8 = 0x000008

Categories

Resources