How can I get the position of bits - java

I have a decimal number which I need to convert to binary and then find the position of one's in that binary representation.
Input is 5 whose binary is 101 and Output should be
1
3
Below is my code which only provides output as 2 instead I want to provide the position of one's in binary representation. How can I also get position of set bits starting from 1?
public static void main(String args[]) throws Exception {
System.out.println(countBits(5));
}
private static int countBits(int number) {
boolean flag = false;
if (number < 0) {
flag = true;
number = ~number;
}
int result = 0;
while (number != 0) {
result += number & 1;
number = number >> 1;
}
return flag ? (32 - result) : result;
}

Your idea of having countBits return the result, instead of putting a System.out.println inside the method, is generally the best approach. If you want it to return a list of bit positions, the analogue would be to have your method return an array or some kind of List, like:
private static List<Integer> bitPositions(int number) {
As I mentioned in my comments, you will make life a lot easier for yourself if you use >>> and get rid of the special code to check for negatives. Doing this, and adapting the code you already have, gives you something like
private static List<Integer> bitPositions(int number) {
List<Integer> positions = new ArrayList<>();
int position = 1;
while (number != 0) {
if (number & 1 != 0) {
positions.add(position);
}
position++;
number = number >>> 1;
}
return positions;
}
Now the caller can do what it wants to print the positions out. If you use System.out.println on it, the output will be [1, 3]. If you want each output on a separate line:
for (Integer position : bitPositions(5)) {
System.out.println(position);
}
In any case, the decision about how to print the positions (or whatever else you want to do with them) is kept separate from the logic that computes the positions, because the method returns the whole list and doesn't have its own println.
(By the way, as Alex said, it's most common to think of the lower-order bit as "bit 0" instead of "bit 1", although I've seen hardware manuals that call the low-order bit "bit 31" and the high-order bit "bit 0". The advantage of calling it "bit 0" is that a 1 bit in position N represents the value 2N, making things simple. My code example calls it "bit 1" as you requested in your question; but if you want to change it to 0, just change the initial value of position.)

Binary representation: Your number, like anything on a modern day (non-quantum) computer, is already a binary representation in memory, as a sequence of bits of a given size.
Bit operations
You can use bit shifting, bit masking, 'AND', 'OR', 'NOT' and 'XOR' bitwise operations to manipulate them and get information about them on the level of individual bits.
Your example
For your example number of 5 (101) you mentioned that your expected output would be 1, 3. This is a bit odd, because generally speaking one would start counting at 0, e.g. for 5 as a byte (8 bit number):
76543210 <-- bit index
5 00000101
So I would expect the output to be 0 and 2 because the bits at those bit indexes are set (1).
Your sample implementation shows the code for the function
private static int countBits(int number)
Its name and signature imply the following behavior for any implementation:
It takes an integer value number and returns a single output value.
It is intended to count how many bits are set in the input number.
I.e. it does not match at all with what you described as your intended functionality.
A solution
You can solve your problem using a combination of a 'bit shift' (>>) and an AND (&) operation.
int index = 0; // start at bit index 0
while (inputNumber != 0) { // If the number is 0, no bits are set
// check if the bit at the current index 0 is set
if ((inputNumber & 1) == 1)
System.out.println(index); // it is, print its bit index.
// advance to the next bit position to check
inputNumber = inputNumber >> 1; // shift all bits one position to the right
index = index + 1; // so we are now looking at the next index.
}
If we were to run this for your example input number '5', we would see the following:
iteration input 76543210 index result
1 5 00000101 0 1 => bit set.
2 2 00000010 1 0 => bit not set.
3 1 00000001 2 1 => bit set.
4 0 00000000 3 Stop, because inputNumber is 0

You'll need to keep track of what position you're on, and when number & 1 results in 1, print out that position. It look something like:
...
int position = 1;
while (number != 0) {
if((number & 1)==1)
System.out.println(position);
result += number & 1;
position += 1;
number = number >> 1;
}
...

There is a way around working with bit-wise operations to solve your problem.
Integer.toBinaryString(int number) converts an integer to a String composed of zeros and ones. This is handy in your case because you could instead have:
public static void main(String args[]) throws Exception {
countBits(5);
}
public static void countBits(int x) {
String binaryStr = Integer.toBinaryString(x);
int length = binaryStr.length();
for(int i=0; i<length; i++) {
if(binaryStr.charAt(i)=='1')
System.out.println(length-1);
}
}
It bypasses what you might be trying to do (learn bitwise operations in Java), but makes the code look cleaner in my opinion.

The combination of Integer.lowestOneBit and Integer.numberOfTrailingZeros instantly gives the position of the lowest 1-Bit, and returns 32 iff the number is 0.
Therefore, the following code returns the positions of 1-Bits of the number number in ascending order:
public static List<Integer> BitOccurencesAscending(int number)
{
LinkedList<Integer> out = new LinkedList<>();
int x = number;
while(number>0)
{
x = Integer.lowestOneBit(number);
number -= x;
x = Integer.numberOfTrailingZeros(x);
out.add(x);
}
return out;
}

Related

Sum vs XOR menas x+a=x^a ,

Given an integer, 0<= x <=a , find each such that:
x+a=x^a ,
where denotes the bit wise XOR operator. Then print an integer denoting the total number of x's satisfying the criteria above.
for example a=5 then x=0,2
a+x=a^x;
I tried to solve this way. Is there any other way to reduce time complexity.
`public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
int cnt=0;
for(long i=0;i<=n;i++)
{
long m=i^n;
if(n+i==m)
cnt++;
}
System.out.println(cnt);
}`
n can have any bit not set in a and this formula will hold.
This means the number of bits to permutate will be 32 minus the number of bits set in a i.e. Integer.bitCount
long cnt = 1L << (32 - Integer.bitCount(a));
Note if a has 0 or 1 bit set, the number of solutions is greater than Integer.MAX_VALUE.
This solution could help you.
numberOfLeadingZeros give how many zeros before last set bit from left,
and bitCount give how many bits set for value a.
long count = 1L<<(64-Long.numberOfLeadingZeros(a) - Long.bitCount(a));
x+a=x^a
if x=5 and (a=0 or a=2) only two value satisfy this condition x+a=x^a
Logic:- **To check number of zero bit**.
for example x=10, in binary representation of x=1010.
Algorithm:
1010 & 1== 0000 so count=1 and 1010 >>1=101
101 & 1 !=0 so count will remain same 101>>1=10
10 & 1==00 so count = 2 and 10>>1=1
1 & 1 !=0 so again count remain same and 1>>1=0 (exit).
answer will 2 to power count means 4.
int xor(int x)
{
int count=0;
while((x!=0)
{
if((x&1)==0)
count++;
x=x>>1;
}
return 1<<count;
}
this loop will execute only number of bits available. and it will reduce time complexity

Printing PowerSet with help of bit position

Googling around for a while to find subsets of a String, i read wikipedia and it mentions that
.....For the whole power set of S we get:
{ } = 000 (Binary) = 0 (Decimal)
{x} = 100 = 4
{y} = 010 = 2
{z} = 001 = 1
{x, y} = 110 = 6
{x, z} = 101 = 5
{y, z} = 011 = 3
{x, y, z} = 111 = 7
Is there a possible way to implement this through program and avoid recursive algorithm which uses string length?
What i understood so far is that, for a String of length n, we can run from 0 to 2^n - 1 and print characters for on bits.
What i couldn't get is how to map those on bits with the corresponding characters in the most optimized manner
PS : checked thread but couldnt understood this and c++ : Power set generated by bits
The idea is that a power set of a set of size n has exactly 2^n elements, exactly the same number as there are different binary numbers of length at most n.
Now all you have to do is create a mapping between the two and you don't need a recursive algorithm. Fortunately with binary numbers you have a real intuitive and natural mapping in that you just add a character at position j in the string to a subset if your loop variable has bit j set which you can easily do with getBit() I wrote there (you can inline it but for you I made a separate function for better readability).
P.S. As requested, more detailed explanation on the mapping:
If you have a recursive algorithm, your flow is given by how you traverse your data structure in the recursive calls. It is as such a very intuitive and natural way of solving many problems.
If you want to solve such a problem without recursion for whatever reason, for instance to use less time and memory, you have the difficult task of making this traversal explicit.
As we use a loop with a loop variable which assumes a certain set of values, we need to make sure to map each value of the loop variable, e.g. 42, to one element, in our case a subset of s, in a way that we have a bijective mapping, that is, we map to each subset exactly once. Because we have a set the order does not matter, so we just need whatever mapping that satisfies these requirements.
Now we look at a binary number, e.g. 42 = 32+8+2 and as such in binary with the position above:
543210
101010
We can thus map 42 to a subset as follows using the positions:
order the elements of the set s in any way you like but consistently (always the same in one program execution), we can in our case use the order in the string
add an element e_j if and only if the bit at position j is set (equal to 1).
As each number has at least one digit different from any other, we always get different subsets, and thus our mapping is injective (different input -> different output).
Our mapping is also valid, as the binary numbers we chose have at most the length equal to the size of our set so the bit positions can always be assigned to an element in the set. Combined with the fact that our set of inputs is chosen to have the same size (2^n) as the size of a power set, we can follow that it is in fact bijective.
import java.util.HashSet;
import java.util.Set;
public class PowerSet
{
static boolean getBit(int i, int pos) {return (i&1<<pos)>0;}
static Set<Set<Character>> powerSet(String s)
{
Set<Set<Character>> pow = new HashSet<>();
for(int i=0;i<(2<<s.length());i++)
{
Set<Character> subSet = new HashSet<>();
for(int j=0;j<s.length();j++)
{
if(getBit(i,j)) {subSet.add(s.charAt(j));}
}
pow.add(subSet);
}
return pow;
}
public static void main(String[] args)
{System.out.println(powerSet("xyz"));}
}
Here is easy way to do it (pseudo code) :-
for(int i=0;i<2^n;i++) {
char subset[];
int k = i;
int c = 0;
while(k>0) {
if(k%2==1) {
subset.add(string[c]);
}
k = k/2;
c++;
}
print subset;
}
Explanation :- The code divides number by 2 and calculates remainder which is used to convert number to binary form. Then as you know only selects index in string which has 1 at that bit number.

How to get the value of Integer.MAX_VALUE in Java without using the Integer class

I have this question that has completely stumped me.
I have to create a variable that equals Integer.MAX_VALUE... (in Java)
// The answer must contain balanced parentesis
public class Exercise{
public static void main(String [] arg){
[???]
assert (Integer.MAX_VALUE==i);
}
}
The challenge is that the source code cannot contain the words "Integer", "Float", "Double" or any digits (0 - 9).
Here's a succinct method:
int ONE = "x".length();
int i = -ONE >>> ONE; //unsigned shift
This works because the max integer value in binary is all ones, except the top (sign) bit, which is zero. But -1 in twos compliment binary is all ones, so by bit shifting -1 one bit to the right, you get the max value.
11111111111111111111111111111111 // -1 in twos compliment
01111111111111111111111111111111 // max int (2147483647)
As others have said.
int i = Integer.MAX_VALUE;
is what you want.
Integer.MAX_VALUE, is a "static constant" inside of the "wrapper class" Integer that is simply the max value. Many classes have static constants in them that are helpful.
Here's a solution:
int ONE = "X".length();
int max = ONE;
while (max < max + ONE) {
max = max + ONE;
}
or lots of variants.
(The trick you were missing is how to "create" an integer value without using a numeric literal or a number wrapper class. Once you have created ONE, the rest is simple ...)
A bit late, but here goes:
int two = "xx".length();
int thirtyone = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".length();
System.out.println(Math.pow(two, thirtyone)-1);
How did I go? :p
I do like that bitshift one though...
The issue is that the answer cannot contain: "Integer", "Float", "Double", and digits (0 - 9)
There are other things in Java which can be represented as an Integer, for example a char:
char aCharacter = 'a';
int asInt = (int) aCharacter;
System.out.println(asInt); //Output: 97
You can also add chars together in this manner:
char aCharacter = 'a';
char anotherCharacter = 'b';
int sumOfCharacters = aCharacter + anotherCharacter;
System.out.println(sumOfCharacters); //Output: 195
With this information, you should be able to work out how to get to 2147483647on your own.
OK, so an Integer can only take certain values. This is from MIN_VALUE to MAX_VALUE where the minimum value is negative.
If you increase an integer past this upper bound the value will wrap around and become the lowest value possible. e.g. MAX_VALUE+1 = MIN_VALUE.
Equally, if you decrease an integer past the lower bound it will wrap around and become the largest possible value. e.g. MIN_VALUE-1 = MAX_VALUE.
Therefore a simple program that instantiates an int, decrements it until it wraps around and returns that value should give you the same value as Integer.MAX_VALUE
public static void main(String [] arg) {
int i = -1
while (i<0) {
i--;
}
System.out.println(i);
}

truncated binary logarithm

I have a question about this problem, and any help would be great!
Write a program that takes one integer N as an
argument and prints out its truncated binary logarithm [log2 N]. Hint: [log2 N] = l is the largest integer ` such that
2^l <= N.
I got this much down:
int N = Integer.parseInt(args[0]);
double l = Math.log(N) / Math.log(2);
double a = Math.pow(2, l);
But I can't figure out how to truncate l while keeping 2^l <= N
Thanks
This is what i have now:
int N = Integer.parseInt(args[0]);
int i = 0; // loop control counter
int v = 1; // current power of two
while (Math.pow(2 , i) <= N) {
i = i + 1;
v = 2 * v;
}
System.out.println(Integer.highestOneBit(N));
This prints out the integer that is equal to 2^i which would be less than N. My test still comes out false and i think that is because the question is asking to print the i that is the largest rather than the N. So when i do
Integer.highestOneBit(i)
the correct i does not print out. For example if i do: N = 38 then the highest i should be 5, but instead it prints out 4.
Then i tried this:
int N = Integer.parseInt(args[0]);
int i; // loop control counter
for (i= 0; Math.pow(2 , i) == N; i++) {
}
System.out.println(Integer.highestOneBit(i));
Where if i make N = 2 i should print out to be 1, but instead it is printing out 0.
I've tried a bunch of things on top of that, but cant get what i am doing wrong. Help would be greatly appreciated. Thanks
I believe the answer you're looking for here is based on the underlying notion of how a number is actually stored in a computer, and how that can be used to your advantage in a problem such as this.
Numbers in a computer are stored in binary - a series of ones and zeros where each column represents a power of 2:
(Above image from http://www.mathincomputers.com/binary.html - see for more info on binary)
The zeroth power of 2 is over on the right. So, 01001, for example, represents the decimal value 2^0 + 2^3; 9.
This storage format, interestingly, gives us some additional information about the number. We can see that 2^3 is the highest power of 2 that 9 is made up of. Let's imagine it's the only power of two it contains, by chopping off all the other 1's except the highest. This is a truncation, and results in this:
01000
You'll now notice this value represents 8, or 2^3. Taking it down to basics, lets now look at what log base 2 really represents. It's the number that you raise 2 to the power of to get the thing your finding the log of. log2(8) is 3. Can you see the pattern emerging here?
The position of the highest bit can be used as an approximation to it's log base 2 value.
2^3 is the 3rd bit over in our example, so a truncated approximation to log base 2(9) is 3.
So the truncated binary logarithm of 9 is 3. 2^3 is less than 9; This is where the less than comes from, and the algorithm to find it's value simply involves finding the position of the highest bit that makes up the number.
Some more examples:
12 = 1100. Position of the highest bit = 3 (starting from zero on the right). Therefore the truncated binary logarithm of 12 = 3. 2^3 is <= 12.
38 = 100110. Position of the highest bit = 5. Therefore the truncated binary logarithm of 38 = 5. 2^5 is <= 38.
This level of pushing bits around is known as bitwise operations in Java.
Integer.highestOneBit(n) returns essentially the truncated value. So if n was 9 (1001), highestOneBit(9) returns 8 (1000), which may be of use.
A simple way of finding the position of that highest bit of a number involves doing a bitshift until the value is zero. Something a little like this:
// Input number - 1001:
int n=9;
int position=0;
// Cache the input number - the loop destroys it.
int originalN=n;
while( n!=0 ){
position++; // Also position = position + 1;
n = n>>1; // Shift the bits over one spot (Overwriting n).
// 1001 becomes 0100, then 0010, then 0001, then 0000 on each iteration.
// Hopefully you can then see that n is zero when we've
// pushed all the bits off.
}
// Position is now the point at which n became zero.
// In your case, this is also the value of your truncated binary log.
System.out.println("Binary log of "+originalN+" is "+position);

Better algorithm for complementing integer value excluding the leading zero binary bits

I will explain first what I mean by "complementing integer value excluding the leading zero binary bits" (from now on, I will call it Non Leading Zero Bits complement or NLZ-Complement for brevity).
For example, there is integer number 92. the binary number is 1011100. If we perform normal bitwise-NOT or Complement, the result is: -93 (signed integer) or 11111111111111111111111110100011 (binary). That's because the leading zero bits are being complemented too.
So, for NLZ-Complement, the leading zero bits are not complemented, then the result of NLZ-complementing of 92 or 1011100 is: 35 or 100011 (binary). The operation is performed by XORing the input value with sequence of 1 bits as much as the non-leading zero value. The illustration:
92: 1011100
1111111 (xor)
--------
0100011 => 35
I had made the java algorithm like this:
public static int nonLeadingZeroComplement(int n) {
if (n == 0) {
return ~n;
}
if (n == 1) {
return 0;
}
//This line is to find how much the non-leading zero (NLZ) bits count.
//This operation is same like: ceil(log2(n))
int binaryBitsCount = Integer.SIZE - Integer.numberOfLeadingZeros(n - 1);
//We use the NLZ bits count to generate sequence of 1 bits as much as the NLZ bits count as complementer
//by using shift left trick that equivalent to: 2 raised to power of binaryBitsCount.
//1L is one value with Long literal that used here because there is possibility binaryBitsCount is 32
//(if the input is -1 for example), thus it will produce 2^32 result whom value can't be contained in
//java signed int type.
int oneBitsSequence = (int)((1L << binaryBitsCount) - 1);
//XORing the input value with the sequence of 1 bits
return n ^ oneBitsSequence;
}
I need an advice how to optimize above algorithm, especially the line for generating sequence of 1 bits complementer (oneBitsSequence), or if anyone can suggest better algorithm?
UPDATE: I also would like to know the known term of this non-leading zero complement?
You can get the highest one bit through the Integer.highestOneBit(i) method, shift this one step left, and then subtract 1. This gets you the correct length of 1s:
private static int nonLeadingZeroComplement(int i) {
int ones = (Integer.highestOneBit(i) << 1) - 1;
return i ^ ones;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
prints
35
obviously #keppil has provided shortest solution. Another solution could be like.
private static int integerComplement(int n){
String binaryString = Integer.toBinaryString(n);
String temp = "";
for(char c: binaryString.toCharArray()){
if(c == '1'){
temp += "0";
}
else{
temp += "1";
}
}
int base = 2;
int complement = Integer.parseInt(temp, base);
return complement;
}
For example,
System.out.println(nonLeadingZeroComplement(92));
Prints answer as 35

Categories

Resources