JAVA Bitwise code purpose , & - java

// following code prints out Letters aA bB cC dD eE ....
class UpCase {
public static void main(String args[]) {
char ch;
for(int i = 0; i < 10; i++) {
ch = (char)('a' + i);
System.out.print(ch);
ch = (char)((int) ch & 66503);
System.out.print(ch + " ")
}
}
}
Still learning Java but struggling to understand bitwise operations. Both codes work but I don't understand the binary reasons behind these codes. Why is (int) casted back to ch and what is 66503 used for that enables it to print out different letter casings.
//following code displays bits within a byte
class Showbits {
public static void main(String args[]) {
int t;
byte val;
val = 123;
for(t = 128; t > 0; t = t/2) {
if((val & t) != 0)
System.out.print("1 ");
else System.out.print("0 ");
}
}
}
//output is 0 1 1 1 1 0 1 1
For this code's output what's the step breakdown to achieve it ? If 123 is 01111011 and 128 as well as 64 and 32 is 10000000 shouldnt the output be 00000000 ? As & turns anything with 0 into a 0 ? Really confused.

Second piece of code(Showbits):
The code is actually converting decimal to binary. The algorithm uses some bit magic, mainly the AND(&) operator.
Consider the number 123 = 01111011 and 128 = 10000000. When we AND them together, we get 0 or a non-zero number depending whether the 1 in 128 is AND-ed with a 1 or a 0.
10000000
& 01111011
----------
00000000
In this case, the answer is a 0 and we have the first bit as 0.
Moving forward, we take 64 = 01000000 and, AND it with 123. Notice the shift of the 1 rightwards.
01000000
& 01111011
----------
01000000
AND-ing with 123 produces a non-zero number this time, and the second bit is 1. This procedure is repeated.
First piece of code(UpCase):
Here 65503 is the negation of 32.
32 = 0000 0000 0010 0000
~32 = 1111 1111 1101 1111
Essentially, we subtract a value of 32 from the lowercase letter by AND-ing with the negation of 32. As we know, subtracting 32 from a lowercase ASCII value character converts it to uppercase.

UpCase
The decimal number 66503 represented by a 32 bit signed integer is 00000000 00000001 00000011 11000111 in binary.
The ASCII letter a represented by a 8 bit char is 01100001 in binary (97 in decimal).
Casting the char to a 32 bit signed integer gives 00000000 00000000 00000000 01100001.
&ing the two integers together gives:
00000000 00000000 00000000 01100001
00000000 00000001 00000011 11000111
===================================
00000000 00000000 00000000 01000001
which casted back to char gives 01000001, which is decimal 65, which is the ASCII letter A.
Showbits
No idea why you think that 128, 64 and 32 are all 10000000. They obviously can't be the same number, since they are, well, different numbers. 10000000 is 128 in decimal.
What the for loop does is start at 128 and go through every consecutive next smallest power of 2: 64, 32, 16, 8, 4, 2 and 1.
These are the following binary numbers:
128: 10000000
64: 01000000
32: 00100000
16: 00010000
8: 00001000
4: 00000100
2: 00000010
1: 00000001
So in each loop it &s the given value together with each of these numbers, printing "0 " when the result is 0, and "1 " otherwise.
Example:
val is 123, which is 01111011.
So the loop will look like this:
128: 10000000 & 01111011 = 00000000 -> prints "0 "
64: 01000000 & 01111011 = 01000000 -> prints "1 "
32: 00100000 & 01111011 = 00100000 -> prints "1 "
16: 00010000 & 01111011 = 00010000 -> prints "1 "
8: 00001000 & 01111011 = 00001000 -> prints "1 "
4: 00000100 & 01111011 = 00000000 -> prints "0 "
2: 00000010 & 01111011 = 00000010 -> prints "1 "
1: 00000001 & 01111011 = 00000001 -> prints "1 "
Thus the final output is "0 1 1 1 1 0 1 1", which is exactly right.

Related

Bitwise operator with negative numbers

Why does..
-23&30 = 8
5&-3 = 5
15&-1 = 15
I understand & with positive numbers but for some reason when a negative number is thrown, I don't understand how the answer is derived.
You should read about 2's complement method of representing negative numbers in binary.
For example:
5 == 00000000 00000000 00000000 00000101
&
-3 == 11111111 11111111 11111111 11111101
= -----------------------------------
5 == 00000000 00000000 00000000 00000101

Reverse bits of a 32 bit unsigned integer

The problem is to reverse the bits of a 32 bit unsigned integer (since Java doesn't have unsigned integers we use long).
Here are two versions of my code. I have two concerns:
(1) why my 1st and 2nd solution don't return the same value (correct or not)
(2) where my 1st and 2nd solution went wrong in not getting the correct answer
//reverse(3) returns 0
public static long reverse(long a) {
long numBits = 32;
long finalResult = 0;
for(int i = 0; i < numBits; i++){
long ithBit = a & (1 << i);
finalResult = finalResult + ithBit * (1 << (numBits - i - 1));
}
return finalResult;
}
Second version:
//reverse(3) return 4294967296
public static long reverse(long a) {
long numBits = 32L;
long finalResult = 0L;
for(long i = 0L; i < numBits; i++){
long ithBit = a & (1L << i);
finalResult = finalResult + ithBit * (1L << (numBits - i - 1L));
}
return finalResult;
}
This code (the solution) returns the correct answer, however:
//reverse(3) returns 3221225472
public static long reverse(long A) {
long rev = 0;
for (int i = 0; i < 32; i++) {
rev <<= 1;
if ((A & (1 << i)) != 0)
rev |= 1;
}
return rev;
}
Thanks!
Let's have a look at your values as you iterate. For clarification, we'll have a look at the intermediate values, so we'll change code to:
int n = (1 << (numBits - i - 1));
long m = ithBit * n;
finalResult = finalResult + m;
Your starting value is 3:
a = 0000 0000 0000 0000 0000 0000 0000 0011
First loop iteration (i = 0):
ithBit = 00000000 00000000 00000000 00000001
n = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
m = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
finalResult = 11111111 11111111 11111111 11111111 10000000 00000000 00000000 00000000
Second loop iteration (i = 1):
ithBit = 00000000 00000000 00000000 00000010
n = 01000000 00000000 00000000 00000000
m = 10000000 00000000 00000000 00000000
finalResult = 00000000 00000000 00000000 00000000
As you can see, the first iterate sets n = 1 << 31, which is -2147483648. In your second version you do n = 1L << 31, which is 2147483648, and that's why your two versions give different results.
As you can also see, you definitely don't want to do the m = ithBit * n part.
Have a look at your number by printing them yourself, and you'll figure it out.
BTW, here's my version. If you have trouble understanding it, try printing the intermediate values to see what's going on.
public static long reverse4(long a) {
long rev = 0;
for (int i = 0; i < 32; i++, a >>= 1)
rev = (rev << 1) | (a & 1);
return rev;
}
since Java doesn't have unsigned integers we use long.
That's generally unecessary since all arithmetic operations except division and comparison result in identical bit patterns for unsigned and signed numbers in two's complement representation, which java uses. And for the latter two ops Integer.divideUnsigned(int, int) and Integer.compareUnsigned(int, int) are available.
The problem is to reverse the bits of a 32 bit unsigned integer
There's Integer.reverse(int)
Relevant docs, spending some time reading them is highly recommended.
Problem with your both examples is that the "i-th bit" isn't a 0 or 1 but rather masked off. In either case, the 31'th bit is 0x8000_0000. In the first case, this is an int, so it is negative, and when converted to a long it stays negative. In the second case it is already a long, so it stays positive. To fix it so it does what you intended, do:
ithBit = (a >>> i) & 1;
By the way, using long is silly; unsigned vs. signed makes no difference as long as you understand that there are two types of shifts in Java.
By the way, all three examples are terrible. If you are doing bit manipulation, you want speed, right? (Why else bother with bits?)
This is how to do it right (not mine, stolen from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits):
a = ((a >>> 1) & 0x55555555) | ((a & 0x55555555) << 1);
a = ((a >>> 2) & 0x33333333) | ((a & 0x33333333) << 2);
a = ((a >>> 4) & 0x0F0F0F0F) | ((a & 0x0F0F0F0F) << 4);
a = ((a >>> 8) & 0x00FF00FF) | ((a & 0x00FF00FF) << 8);
a = ( a >>> 16 ) | ( a << 16);
In both versions you have a logic problem here:
ithBit * (1 << (numBits - i - 1));
because the two numbers multiply to the same bit pattern of bit 31 (the 32nd) being set.
In version 1, the amount added is -2^31 if bit 0 is set because you're bit-shifting an int so the bit-shifted result is int which represents -2^31 as the high bit being set, or 2^31 for every other bit, which is possible due to the auto-cast to long of the result. You have two of each kind of bit (0 and non 0) so the result is zero.
Version 2 has the same problem, but without the negative int issue because you're bit shifting a long. Each bit that is 1 will add 2^31. The number 3 has 2 bits set, so your result is 2 * 2^31 (or 2^32) which is 4294967296.
To fix your logic, use version 2 but remove the multiply by ithBit.

What does ">>" mean in Java? [duplicate]

I have this statement:
Assume the bit value of byte x is 00101011. what is the result of x>>2?
How can I program it and can someone explain me what is doing?
Firstly, you can not shift a byte in java, you can only shift an int or a long. So the byte will undergo promotion first, e.g.
00101011 -> 00000000000000000000000000101011
or
11010100 -> 11111111111111111111111111010100
Now, x >> N means (if you view it as a string of binary digits):
The rightmost N bits are discarded
The leftmost bit is replicated as many times as necessary to pad the result to the original size (32 or 64 bits), e.g.
00000000000000000000000000101011 >> 2 -> 00000000000000000000000000001010
11111111111111111111111111010100 >> 2 -> 11111111111111111111111111110101
The binary 32 bits for 00101011 is
00000000 00000000 00000000 00101011, and the result is:
00000000 00000000 00000000 00101011 >> 2(times)
\\ \\
00000000 00000000 00000000 00001010
Shifts the bits of 43 to right by distance 2; fills with highest(sign) bit on the left side.
Result is 00001010 with decimal value 10.
00001010
8+2 = 10
When you shift right 2 bits you drop the 2 least significant bits. So:
x = 00101011
x >> 2
// now (notice the 2 new 0's on the left of the byte)
x = 00001010
This is essentially the same thing as dividing an int by 2, 2 times.
In Java
byte b = (byte) 16;
b = b >> 2;
// prints 4
System.out.println(b);
These examples cover the three types of shifts applied to both a positive and a negative number:
// Signed left shift on 626348975
00100101010101010101001110101111 is 626348975
01001010101010101010011101011110 is 1252697950 after << 1
10010101010101010100111010111100 is -1789571396 after << 2
00101010101010101001110101111000 is 715824504 after << 3
// Signed left shift on -552270512
11011111000101010000010101010000 is -552270512
10111110001010100000101010100000 is -1104541024 after << 1
01111100010101000001010101000000 is 2085885248 after << 2
11111000101010000010101010000000 is -123196800 after << 3
// Signed right shift on 626348975
00100101010101010101001110101111 is 626348975
00010010101010101010100111010111 is 313174487 after >> 1
00001001010101010101010011101011 is 156587243 after >> 2
00000100101010101010101001110101 is 78293621 after >> 3
// Signed right shift on -552270512
11011111000101010000010101010000 is -552270512
11101111100010101000001010101000 is -276135256 after >> 1
11110111110001010100000101010100 is -138067628 after >> 2
11111011111000101010000010101010 is -69033814 after >> 3
// Unsigned right shift on 626348975
00100101010101010101001110101111 is 626348975
00010010101010101010100111010111 is 313174487 after >>> 1
00001001010101010101010011101011 is 156587243 after >>> 2
00000100101010101010101001110101 is 78293621 after >>> 3
// Unsigned right shift on -552270512
11011111000101010000010101010000 is -552270512
01101111100010101000001010101000 is 1871348392 after >>> 1
00110111110001010100000101010100 is 935674196 after >>> 2
00011011111000101010000010101010 is 467837098 after >>> 3
>> is the Arithmetic Right Shift operator. All of the bits in the first operand are shifted the number of places indicated by the second operand. The leftmost bits in the result are set to the same value as the leftmost bit in the original number. (This is so that negative numbers remain negative.)
Here's your specific case:
00101011
001010 <-- Shifted twice to the right (rightmost bits dropped)
00001010 <-- Leftmost bits filled with 0s (to match leftmost bit in original number)
public class Shift {
public static void main(String[] args) {
Byte b = Byte.parseByte("00101011",2);
System.out.println(b);
byte val = b.byteValue();
Byte shifted = new Byte((byte) (val >> 2));
System.out.println(shifted);
// often overloked are the methods of Integer
int i = Integer.parseInt("00101011",2);
System.out.println( Integer.toBinaryString(i));
i >>= 2;
System.out.println( Integer.toBinaryString(i));
}
}
Output:
43
10
101011
1010
byte x = 51; //00101011
byte y = (byte) (x >> 2); //00001010 aka Base(10) 10
You can't write binary literals like 00101011 in Java so you can write it in hexadecimal instead:
byte x = 0x2b;
To calculate the result of x >> 2 you can then just write exactly that and print the result.
System.out.println(x >> 2);
You can use e.g. this API if you would like to see bitString presentation of your numbers. Uncommons Math
Example (in jruby)
bitString = org.uncommons.maths.binary.BitString.new(java.math.BigInteger.new("12").toString(2))
bitString.setBit(1, true)
bitString.toNumber => 14
edit: Changed api link and add a little example
00101011 = 43 in decimal
class test {
public static void main(String[] args){
int a= 43;
String b= Integer.toBinaryString(a >> 2);
System.out.println(b);
}
}
Output:
101011 becomes 1010

count leading zeros (clz) or number of leading zeros (nlz) in Java

I need int 32 in binary as 00100000 or int 127 in binary 0111 1111.
The variant Integer.toBinaryString returns results only from 1.
If I build the for loop this way:
for (int i= 32; i <= 127; i + +) {
System.out.println (i);
System.out.println (Integer.toBinaryString (i));
}
And from binary numbers I need the number of leading zeros (count leading zeros (clz) or number of leading zeros (nlz)) I really meant the exact number of 0, such ex: at 00100000 -> 2 and at 0111 1111 - > 1
How about
int lz = Integer.numberOfLeadingZeros(i & 0xFF) - 24;
int tz = Integer.numberOfLeadingZeros(i | 0x100); // max is 8.
Count the number of leading zeros as follows:
int lz = 8;
while (i)
{
lz--;
i >>>= 1;
}
Of course, this supposes the number doesn't exceed 255, otherwise, you would get negative results.
Efficient solution is int ans = 8-(log2(x)+1)
you can calculate log2(x)= logy (x) / logy (2)
public class UtilsInt {
int leadingZerosInt(int i) {
return leadingZeros(i,Integer.SIZE);
}
/**
* use recursion to find occurence of first set bit
* rotate right by one bit & adjust complement
* check if rotate value is not zero if so stop counting/recursion
* #param i - integer to check
* #param maxBitsCount - size of type (in this case int)
* if we want to check only for:
* positive values we can set this to Integer.SIZE / 2
* (as int is signed in java - positive values are in L16 bits)
*/
private synchronized int leadingZeros(int i, int maxBitsCount) {
try {
logger.debug("checking if bit: "+ maxBitsCount
+ " is set | " + UtilsInt.intToString(i,8));
return (i >>>= 1) != 0 ? leadingZeros(i, --maxBitsCount) : maxBitsCount;
} finally {
if(i==0) logger.debug("bits in this integer from: " + --maxBitsCount
+ " up to last are not set (i'm counting from msb->lsb)");
}
}
}
test statement:
int leadingZeros = new UtilsInt.leadingZerosInt(255); // 8
test output:
checking if bit: 32 is set |00000000 00000000 00000000 11111111
checking if bit: 31 is set |00000000 00000000 00000000 01111111
checking if bit: 30 is set |00000000 00000000 00000000 00111111
checking if bit: 29 is set |00000000 00000000 00000000 00011111
checking if bit: 28 is set |00000000 00000000 00000000 00001111
checking if bit: 27 is set |00000000 00000000 00000000 00000111
checking if bit: 26 is set |00000000 00000000 00000000 00000011
checking if bit: 25 is set |00000000 00000000 00000000 00000001
bits in this integer from: 24 up to last are not set (i'm counting from msb->lsb)

Bitshifting in Java

I'm trying to understand how bit shift works. Can someone please explain the meaning of this line:
while ((n&1)==0) n >>= 1;
where n is an integer and give me an example of a n when the shift is executed.
Breaking it down:
n & 1 will do a binary comparison between n, and 1 which is 00000000000000000000000000000001 in binary. As such, it will return 00000000000000000000000000000001 when n ends in a 1 (positive odd or negative even number) and 00000000000000000000000000000000 otherwise.
(n & 1) == 0 will hence be true if n is even (or negative odd) and false otherwise.
n >> = 1 is equivalent to n = n >> 1. As such it shifts all bits to the right, which is roughly equivalent to a division by two (rounding down).
If e.g. n started as 12 then in binary it would be 1100. After one loop it will be 110 (6), after another it will be 11 (3) and then the loop will stop.
If n is 0 then after the next loop it will still be 0, and the loop will be infinite.
Lets n be 4 which in binary is represented as:
00000000 00000000 00000000 00000100
(n&1) bitwise ands the n with 1. 1 has the binary representation of:
00000000 00000000 00000000 00000001
The result of the bitwise anding is 0:
00000000 00000000 00000000 00000100 = n
00000000 00000000 00000000 00000001 = 1
------------------------------------
00000000 00000000 00000000 00000000 = 0
so the condition of while is true. Effectively (n&1) was used to extract the least significant bit of the n.
In the while loop you right shift(>>) n by 1. Right shifting a number by k is same as dividing the number by 2^k.
n which is now 00000000 00000000 00000000 00000100 on right shifting once becomes
00000000 00000000 00000000 00000010 which is 2.
Next we extract the LSB(least significant bit) of n again which is 0 and right shift again to give 00000000 00000000 00000000 0000001 which is 1.
Next we again extract LSB of n, which is now 1 and the loop breaks.
So effectively you keep dividing your number n by 2 till it becomes odd as odd numbers have their LSB set.
Also note that if n is 0 to start with you'll go into an infinite loop because no matter how many times you divide 0 by 2 you'll not get a odd number.
Assume n = 12. The bits for this would be 1100 (1*8 + 1*4 + 0*2 + 0*1 = 12).
The first time through the loop n & 1 == 0 because the last digit of 1100 is 0 and when you AND that with 1, you get 0. So n >>= 1 will cause n to change from 1100 (12) to 110 (6). As you may notice, shifting right has the same effect as dividing by 2.
The last bit is still zero, so n & 1 will still be 0, so it will shift right one more time. n>>=1 will cause it to shift one more digit to the right changing n from 110 (6) to 11 (3).
Now you can see the last bit is 1, so n & 1 will be 1, causing the while loop to stop executing. The purpose of the loop appears to be to shift the number to the right until it finds the first turned-on bit (until the result is odd).
Let's assume equals 42 (just because):
int n = 42;
while ((n & 1) == 0) {
n >>= 1;
}
Iteration 0:
n = 42 (or 0000 0000 0000 0000 0000 0000 0010 1010)
n & 1 == 0 is true (because n&1 = 0 or 0000 0000 0000 0000 0000 0000 0000 0000)
Iteration 1:
n = 21 (or 0000 0000 0000 0000 0000 0000 0001 0101)
n & 1 == 0 is false (because n & 1 == 1 or 0000 0000 0000 0000 0000 0000 0000 0001)
What it does:
Basically, you loop divides n by 2 as long as n is an even number:
n & 1 is a simple parity check,
n >>= 1 shifts the bits to the right, which just divides by 2.
for example if n was
n= b11110000
then
n&1= b11110000 &
b00000001
---------
b00000000
n>>=1 b11110000 >> 1
---------
b01111000
n= b01111000
if the loop continues it should be
n= b00001111
n & 1 is actually a bitwise AND operataion. Here the bit pattern of n would be ANDED against the bit pattern of 1. Who's result will be compared against zero. If yes then n is right shifted 1 times. You can take the one right shift as division by 2 and so on.

Categories

Resources