Computing Hamming weight, also called popcount in Java? - java

I am not sure how to translate this from C++ to Java.
It is a function that computes the Hamming weight.
/** This is popcount_3() from:
* http://en.wikipedia.org/wiki/Hamming_weight */
unsigned int popcnt32(uint32_t n) const
{
n -= ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
return (((n + (n >> 4))& 0xF0F0F0F)* 0x1010101) >> 24;
}
More concretely, I don't know what to use instead of uint32_t,
and if I use that type whatever it is, can I just leave the rest
code unchanged?
Thanks

It's implemented for you in Integer.bitCount(int i)

Related

Reverse bits of a unsigned integer

The below two code is the method can invert the bits of an unsigned 32 bits integer. But What's the difference of the two code below?
Why the first code is wrong and the second code is correct.
I can't see the difference of these two.
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | (n & (1 << i));
}
return result;
}
public int reverseBits(int n) {
int result = 0;
for (int i = 0; i < 32; i++) {
result = result << 1 | ((n >> i) & 1);
}
return result;
}
Appreciate any help.
The first code is wrong, because it extracts given bit and puts it in the same position of the resulting number. Suppose you are on iteration i = 5. Then n & (1 << 5) = n & 32 which is either 0 or 0b100000. The intention is to put the one-bit to the lowest position, but when performing | operation it actually puts it to the same position #5. On the consequent iterations you move this bit even higher, so you practically have all the bits or'ed at the highest bit position.
Please note that there are more effective algorithms to reverse bits like one implemented in standard JDK Integer.reverse method:
public static int reverse(int i) {
// HD, Figure 7-1
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;
}
It has to do with whether the bit being grabbed from n is being stored in the rightmost bit of the result or being stored back into the same position.
Suppose n is 4 (for example).
Then when i is 2, the expression (n & (1 << i))
becomes (4 & (1 << 2)), which should equal 4 & 4, so it evaluates to 4.
But the expression ((n >> i) & 1)
becomes ((4 >> 2) & 1), which should equal 1 & 1, so it evaluates to 1.
The two expressions do not have the same result.
But both versions of the function try to use those results in the exact same way, so the two versions of the function do not have the same result.

Getting wrong answer after performing mathematical operations

I am trying to perform some mathematical calculations in java but the expected result is not getting. Since the same snippet of the code when I run in "C" programme then it works correctly please guide me what is getting wrong in the code.
The value that is getting passed to the function is.
v0=1970012 and v1=1970012 and iterations= 32
The "C" Programme snippet looks something like this
void encipher(uint8_t iterations, uint32_t v0, uint32_t v1)
{
uint8_t i;
int key[]={0x02a4bd14,0x6c753bde,0x4ac819ad,0x6da4a0c4};
uint32_t sum, delta;
sum=0x32d61b8e;
delta=0x9E3779B9;
for (i=0; i < iterations; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
en_result0=v0; en_result1=v1;
}
The en_result0 and en_result1 are the global varaibles and are of the same type as v0 and v1
Similarly the Java snippet code looks something like this.
public static void encipher(int iterations, int v0, int v1)
{
int i;
int key[]={0x02a4bd14,0x6c753bde,0x4ac819ad,0x6da4a0c4};
int sum, delta;
sum=0x32d61b8e;
delta=0x9E3779B9;
for (i=0; i < iterations; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
en_result0=v0; en_result1=v1;
}
Here also the en_result0 and en_result1 are global variables of type int
The answer in "C" programme en_result0=3755627302 and en_result1=3278396279
And
The Answer in "java" Programme en_result0=-1152914223 and en_result1=1706153302
Just not Find where is getting wrong Please Help me to find The solution
You should get the correct results when you replace the >> operator by Java's >>> operator. It does an unsigned right shift, just what the C code achieves with declaring unsigned variables and doing right shifts.
The other operations are harmless and give the same results, no matter if signed or unsigned.
Note that to print the results, you should do something like:
println( ((long) result) & 0xFFFFFFFFL ); // where result is int
or use an appropriate printf format (i.e. print it in hex).
One issue is that the C code is using unsigned integer types, whereas the Java code is using signed types (there are no unsigned integers in Java).
One possibility is to use Java's long in place of C's uint32_t. It's signed but is double the width. You may also need to change the types of v0, v1, en_result0 and en_result1 to avoid integer overflow.
it is because of the value range of an integer in java.
The int data type is a 32-bit signed two's complement integer. It has a minimum value of > -2,147,483,648 and a maximum value of 2,147,483,647 (inclusive)
use a long instead of int

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);
}

Obtaining reversed Integer in Java

There is a method in Java that reverses bits in an Integer reverseBytes(). I wanted to try another implementation and this is what I have:
public static int reverse(int num) {
int num_rev = 0;
for (int i = 0; i < Integer.SIZE; i++) {
System.out.print((num >> i) & 1);
if (((num >> i) & 1)!=0) {
num_rev = num_rev | (int)Math.pow(2, Integer.SIZE-i);
}
}
return num_rev;
}
The result num_rev is not correct. Does anyone have any idea how to "reconstruct" the value? Maybe there is a better way to perform it?
Thanks for any suggestions.
The normal way would to reverse bits would be via bit manipulation, and certainly not via floating point math routines!
e.g (nb: untested).
int reverse(int x) {
int y = 0;
for (int i = 0; i < 32; ++i) {
y <<= 1; // make space
y |= (x & 1); // copy LSB of X into Y
x >>>= 1; // shift X right
}
return y;
}
Because x is right shifted and y left shifted the result is that the original LSB of x eventually becomes the MSB of y.
A nice (and reasonably well known) method is this:
unsigned int reverse(unsigned int x)
{
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
return ((x >> 16) | (x << 16));
}
This is actually C code, but as Java doesn't have unsigned types to port to Java all you should need to do is remove the unsigned qualifiers and use >>> instead of >> to ensure that you don't get any "sign extension".
It works by first swapping every other bit, then every other pair of bits, then every other nybble, then every other byte, and then finally the top and bottom 16-bit words. This actually works :)
There are 2 problems with your code:
You're using an int cast. You should be doing (long)Math.pow(... The problem with int casting is that pow(2, n) will always be a positive number, so pow(2, 31) casted to an int will be rounded to (2^31)-1, because that's the largest positive int. The bit field for 2^31-1 is 0x7ffffff, but in this case you want 0x80000000, which is exactly what the lower 32 bits of the casted long will be.
You're doing pow(2, Integer.Size - i). That should be Integer.SIZE - i - 1. You basically want to take bit 0 to the last bit, bit 1 to the second last and so on. However, the last bit is bit 31, not bit 32. Your code right now is trying to set bit 0 to bit Integer.SIZE-0 == 32, so you need to subtract 1.
The above is assuming this is just for fun. If you really need to reverse bits, however, please don't use floating point ops. Do what some of the another answers suggest.
why you don't want to use:
public static int reverseBytes(int i) {
return ((i >>> 24) ) |
((i >> 8) & 0xFF00) |
((i << 8) & 0xFF0000) |
((i << 24));
}
edited:
Integer has also:
public static int reverse(int i)
Returns the value obtained by
reversing the order of the bits in the
two's complement binary representation
of the specified int value.

number of 1's in 32 bit number

I am lookin for a method to have number of 1's in 32 bit number
without using a loop in between.
can any body help me and provide me the code or algorithm
to do so.
Thanks in advance.
See Integer.bitCount(int). You can refer to the source code if you want to see how it works; many of the Integer class's bit twiddling routines are taken from Hacker's Delight.
See the canonical reference: Bit Twiddling Hacks
Short, obscenely optimized answer (in C):
int pop(unsigned x) {
x = x - ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x + (x >> 4)) & 0x0F0F0F0F;
x = x + (x >> 8);
x = x + (x >> 16);
return x & 0x0000003F;
}
To see why this magic works, see The Quest for an Accelerated Population Count by Henry S. Warren, Jr. chapter 10 in Beautiful Code.
Split the 32 bit number into four 8 bit numbers (see bit shifting operator, casting etc.)
Then use a lookup with 256 entries that converts the 8 bit number into a count of bits set. Add the four results, presto!
Also, see what Mitch Wheat said - bit fiddling can be a lot of fun ;)
You can define it recursively:
int bitcount(int x) {
return (x==0) ? 0 : (x & 1 + bitcount(x/2));
}
The code above is not tested, and probably only works for x>=0. Hopefully, you will get the idea anyways...
My personal favourite, directly from Bit Twiddling Hacks:
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
Following is JDK 1.5 implementation of of Integer.bitCount
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}

Categories

Resources