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
Related
I'm basically trying to remove a bit from an integer at a specific index. That is, I do not want to unset/clear the bit; I actually want to strip it, so that every higher bit moves down, replacing the respective bit at its position. Visually, this could be compared to deleting an element from an array or removing a character from a string.
For the sake of clarity, some examples:
1011011 (original number)
^ index = 2
0101111 (result)
10000000000000000000000000000001
^ index = 31
00000000000000000000000000000001
1111111111111111111111111111110
^ index = 0
0111111111111111111111111111111
Full of confidence, I started shifting some bits, and came up with the following Java method...
public static int removeBit(int num, int i) {
int out = (num >>> (i + 1)) << i;
out |= (num << (32 - i)) >>> (32 - i);
return out;
}
... which almost always works, except for some extreme cases:
10000000000000000000000000000001 (= Integer.MAX_VALUE - 1)
^ index = 31, results in:
10000000000000000000000000000001
1011011
^ index = 0, results in:
1111111
In other words, if the index is 0 or 31 (least or most significant bit), my method will output garbage.
I can't seem to wrap my head around it, and that's why I'm asking: How can I remove an arbitrary bit in a 32-bit integer?
I'm especially looking for the most performant way to do it in Java (smallest possible memory and CPU consumption), since this operation has to run at least a couple million times. That's why something like "convert it into a string, remove the char and convert it back" is out of the question.
As explained in the comments, the shift counts rolled over to >= 32, which caused trouble.
Anyway, let's derive a way to do it.
Start by considering the two "pieces", the low piece (which gets copied in its original position and may be anywhere between 0 .. 31 bits long) and the high piece (which gets shifted down by one, and can also be between 0 .. 31 bits long). The total length of the pieces is always 31.
The mask for the low piece is obvious: ~(-1 << i)
Which makes the mask for the high piece obvious: ~lowmask << 1. The high piece is shifted anyway, so that shift can go.
Now all that's left is to take the pieces and OR them together, and you would get
static int removeBit(int x, int i)
{
int mask = ~(-1 << i);
return (x & mask) | ((x >>> 1) & ~mask);
}
Throw out the double negation:
static int removeBit(int x, int i)
{
int mask = -1 << i;
return (x & ~mask) | ((x >>> 1) & mask);
}
Just mask out the bits needed, no need to shift back and forth
public static int removeBit(int num, int index) {
int mask = (1 << index) - 1;
return ((num & ((~mask) << 1)) >>> 1) | (num & mask);
}
or
public static int removeBit(int num, int index) {
int mask = (1 << index) - 1;
return ((num >>> 1) & ~mask) | (num & mask);
}
Some platforms have very efficient parallel bit extract so if you can do the job in JNI or if Java has some intrinsic similar to Bmi2.ParallelBitExtract then you can do like this
public static int removeBit(int num, int index) {
return Bmi2.ParallelBitExtract(num, ~(1 << index));
}
If it is important to use the minimum number of instructions, for these kind of bit shuffling it is often best to calculate the bits that need to be toggled and then use xor to apply that. Also here this saves one instruction compared to harold's solution:
static int removeBit(int x, int i)
{
int mask = -1 << i;
return ((x ^ (x >>> 1)) & mask) ^ x;
}
or
static int removeBit(int x, int i)
{
return (((x ^ (x >>> 1)) >>> i) << i) ^ x;
}
I'm trying to count the number of set bits in a byte but I appear to be running into some issues I can't find answers to.
My code currently looks like
public static int numBits(byte input){
int count = 0;
while (input != 0){
if ((input & 1)==1){
count++;
}
input >>= 1;
}
return count;
}
It appeared to work fine until I tried x = -1.
This ended up creating an infinite loop as value 1 bits were being inserted. So I stumbled upon
Java: right shift on negative number
which to my interpretation meant I should use input >>>= 1; but this still led to an infinite loop.
So I tried to figure out what was going on by trying
byte x = -1;
System.out.println(x >>> 1);
System.out.println(x >> 1);
which lead to
2147483647
-1
leaving me more confused. Where did the number 2147483647 come from and where might I be making a logic mistake?
The >>> operator means shift to the right, but do not sign-extend.
Your trial is pretty close, but you're not actually modifying x, so you can do:
int x = -1;
x = x >>> 1;
System.out.println(x);
x = x >> 1; // highest bit = 0 now
System.out.println(x);
Which will yield
2147483647
1073741823
Notice that I'm using int rather than byte here, since the result of bit shifts coerces the input to at least be integer sized.
Interestingly, when you run:
byte input = -1;
input = (byte) (input >>> 1);
The result is still -1. This is because of the type coercion happening with this operator mentioned above. To prevent this from affecting you, you can mask the bits of input to make sure you only take the first 8:
byte input = -1;
input = (byte) ((input & 0xFF) >>> 1);
Putting this together, if you were to run:
byte input = -1;
input = (byte) ((input & 0xFF) >>> 1);
System.out.println(input);
input = (byte) ((input & 0xFF) >> 1);
System.out.println(input);
You get the expected results:
127
63
This is all being caused by the way signed integers are stored as binary values. The way the highest bit of the number determines the sign (sort of—zero makes things weird), and the sign was being preserved with the arithmetic shift. Your print statements are giving weird results because the results are being promoted to int values instead of bytes.
If you want a really simple fix for this, you can just use an int to store your value, but make sure to mask off everything but the lowest-order byte:
public static int numBits(byte inByte){
int count = 0;
int input = inByte & 0xFF;
while (input != 0){
if ((input & 1)==1){
count++;
}
input >>= 1;
}
return count;
}
Like I said in my comment above, you should really read about Two's complement representation of signed numbers in binary. If you understand how negative numbers are represented, and the difference between arithmetic/logical shifts, all of that will make perfect sense.
You might find how the JVM actually does it is interesting. Note: there is only 8 bits so you don't really need a loop.
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;
}
NOTE: On the x86/x64, the JVM replaces this with an intrinsic. i.e. it uses a single machine code instruction. If you copy this method and compare it will calling the original it is 3x slower as the JVM only replaces a hard coded list of methods, so it will replace Integer.bitCOunt, but not a copy.
In short, use the built in method instead of re-inventing it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Best algorithm to count the number of set bits in a 32-bit integer?
How do I count the number of 1's a number will have in binary?
So let's say I have the number 45, which is equal to 101101 in binary and has 4 1's in it. What's the most efficient way to write an algorithm to do this?
Instead of writing an algorithm to do this its best to use the built in function. Integer.bitCount()
What makes this especially efficient is that the JVM can treat this as an intrinsic. i.e. recognise and replace the whole thing with a single machine code instruction on a platform which supports it e.g. Intel/AMD
To demonstrate how effective this optimisation is
public static void main(String... args) {
perfTestIntrinsic();
perfTestACopy();
}
private static void perfTestIntrinsic() {
long start = System.nanoTime();
long countBits = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++)
countBits += Integer.bitCount(i);
long time = System.nanoTime() - start;
System.out.printf("Intrinsic: Each bit count took %.1f ns, countBits=%d%n", (double) time / Integer.MAX_VALUE, countBits);
}
private static void perfTestACopy() {
long start2 = System.nanoTime();
long countBits2 = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++)
countBits2 += myBitCount(i);
long time2 = System.nanoTime() - start2;
System.out.printf("Copy of same code: Each bit count took %.1f ns, countBits=%d%n", (double) time2 / Integer.MAX_VALUE, countBits2);
}
// Copied from Integer.bitCount()
public static int myBitCount(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;
}
prints
Intrinsic: Each bit count took 0.4 ns, countBits=33285996513
Copy of same code: Each bit count took 2.4 ns, countBits=33285996513
Each bit count using the intrinsic version and loop takes just 0.4 nano-second on average. Using a copy of the same code takes 6x longer (gets the same result)
The most efficient way to count the number of 1's in a 32-bit variable v I know of is:
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // c is the result
Updated: I want to make clear that it's not my code, actually it's older than me. According to Donald Knuth (The Art of Computer Programming Vol IV, p 11), the code first appeared in the first textbook on programming, The Preparation of Programs for an Electronic Digital Computer by Wilkes, Wheeler and Gill (2nd Ed 1957, reprinted 1984). Pages 191–193 of the 2nd edition of the book presented Nifty Parallel Count by D B Gillies and J C P Miller.
See Bit Twidling Hacks and study all the 'counting bits set' algorithms. In particular, Brian Kernighan's way is simple and quite fast if you expect a small answer. If you expect an evenly distributed answer, lookup table might be better.
This is called Hamming weight. It is also called the population count, popcount or sideways sum.
The following is either from "Bit Twiddling Hacks" page or Knuth's books (I don't remember). It is adapted to unsigned 64 bit integers and works on C#. I don't know if the lack of unsigned values in Java creates a problem.
By the way, I write the code only for reference; the best answer is using Integer.bitCount() as #Lawrey said; since there is a specific machine code operation for this operation in some (but not all) CPUs.
const UInt64 m1 = 0x5555555555555555;
const UInt64 m2 = 0x3333333333333333;
const UInt64 m4 = 0x0f0f0f0f0f0f0f0f;
const UInt64 h01 = 0x0101010101010101;
public int Count(UInt64 x)
{
x -= (x >> 1) & m1;
x = (x & m2) + ((x >> 2) & m2);
x = (x + (x >> 4)) & m4;
return (int) ((x * h01) >> 56);
}
public int f(int n)
{
int result = 0;
for(;n > 0; n = n >> 1)
result += ((n & 1) == 1 ? 1 : 0);
return result;
}
The following Ruby code works for positive numbers.
count = 0
while num > 1
count = (num % 2 == 1) ? count + 1 : count
num = num >> 1
end
count += 1
return count
The fastest I have used and also seen in a practical implementation (in the open source Sphinx Search Engine) is the MIT HAKMEM algorithm. It runs superfast over a very large stream of 1's and 0's.
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);
}
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.