Java simple bitwise operation - java

We are given integer n, value v (v=0 or 1) and a position p. Write a sequence of operators that modifies n to hold the value v at the position p from the binary representation of n. Example:
n = 5 (00000101), p=3, v=1 -> 13 (00001101)
n = 5 (00000101), p=2, v=0 -> 1 (00000001)
This is my code:
int n1 = 35;
int p1 = 3;
int v = 1;
n1 = n1 + (v << p1);
System.out.println(n1);
It works when the v=1 but when the v=0 it doesn't.

Since you want to "set" the index to a value, you need one of two operations
'and' will set 0 values at an index to 0, but won't work for 1 values
'or' will set 1 values at an index to 1, but won't work for 0 values
Now all you need to do is put the right number at the right index. This can be done by shifting 1.
'<<' moves the 1 a number of places
for example
'1 << 3' shifts the 1 three places, resulting in '00001000'
remember, we need a zero for some of the operations, to get a zero in that place, you need to invert the bits
'not' or '~' flips all the bits in a number
~00001000 yeilds 11110111
Now we can have a 1 or a 0 in the index we wish, and only need to use an if statement to pick the right one based on the desired operation and apply the corresponding and or or operation to set the bit we want.

Okay I think that is going to work, but how to print the result properly on the console?
// Swapping i and j: i ^= j, j ^= i, i ^= j;
// Getting the pth byte: (n >> p) & 1
// Setting the pth byte to v: (v == 0) ? (n & ~(1 << p)) : (n | 1 << p)
static int Exchange(int n, int i, int j)
{
n = ((n >> i) & 1 ^ (n >> j) & 1) == 0 ? (n & ~(1 << j)) : (n | 1 << j);
n = ((n >> i) & 1 ^ (n >> j) & 1) == 0 ? (n & ~(1 << i)) : (n | 1 << i);
n = ((n >> i) & 1 ^ (n >> j) & 1) == 0 ? (n & ~(1 << j)) : (n | 1 << j);
return n;
}
public static void main(String[] arguments)
{
int n = 56, p = 3, q = 24, k = 3;
while (k-- != 0) n = Exchange(n, p++, q++);
}

Related

Left Shift Operator, Java : How does 0 / 2 doesn't throws error

I was looking into this video, for a really famous question for bit manipulation
He wrote this statement
count -= (1 << ((length - 1) / 2));
I am not able to understand.
Consider if I pass length as 1, why does this statement doesn't throws ArithmeticException
for 0 / 2.
I am missing out the core fundamental over here.
Please help me out here.
Here is the full code for reference:
public int solve(int A) {
if(A == 0)
return 0;
int result = 1;
int length = 1;
int count = 1;
while(count < A) {
length++;
count += (1 << ((length - 1) / 2));
}
count -= (1 << ((length - 1) / 2));
int offset = A - count - 1;
result |= (1 << (length - 1));
result |= offset << (length / 2);
int halfShiftedNumber = (result >> (length / 2));
int reversedNumber = getReversedNumber(halfShiftedNumber);
result |= reversedNumber;
return result;
}
int getReversedNumber(int A) {
int result = 0;
while(A > 0) {
int lsb = (A & 1);
result |= lsb;
result = result << 1;
A = A >> 1;
}
result = result >> 1;
return result;
}
What if I pass 1 as an input to the function.. it should throw ArithmeticException.
But its not..
Can anyone help me, explaining this basic stuff.
Thanks!
0 / NaturalNumber is a valid mathematical operation that will result a 0. So programming languages support the operation. (this applies to negative and floating point numbers too)
In the related context, 0 as denominator is undefined.
So, for AnyNumber / 0 operation, programming languages can throw exception.
Issues to consider
Please be aware that when length is zero or negative (so that length-1 is negative), then it will result in unexpected result.
In the context of integer, somenumber << -value is similar to somenumber << ((32 - value) % 32)
In the context of long, somenumber << -value is similar to somenumber << ((64 - value) % 64)

How to remove the nth hexadecimal digit of a integer number without using Strings?

Consider a hexadecimal integer value such as n = 0x12345, how to get 0x1235 as result by doing remove(n, 3) (big endian)?
For the inputs above I think this can be achieved by performing some bitwising steps:
partA = extract the part from index 0 to targetIndex - 1 (should return 0x123);
partB = extract the part from targetIndex + 1 to length(value) - 1 (0x5);
result, then, can be expressed by ((partA << length(partB) | partB), giving the 0x1235 result.
However I'm still confused in how to implement it, once each hex digit occupies 4 spaces. Also, I don't know a good way to retrieve the length of the numbers.
This can be easily done with strings however I need to use this in a context of thousands of iterations and don't think Strings is a good idea to choose.
So, what is a good way to this removing without Strings?
Similar to the idea you describe, this can be done by creating a mask for both the upper and the lower part, shifting the upper part, and then reassembling.
int remove(int x, int i) {
// create a mask covering the highest 1-bit and all lower bits
int m = x;
m |= (m >>> 1);
m |= (m >>> 2);
m |= (m >>> 4);
m |= (m >>> 8);
m |= (m >>> 16);
// clamp to 4-bit boundary
int l = m & 0x11111110;
m = l - (l >>> 4);
// shift to select relevant position
m >>>= 4 * i;
// assemble result
return ((x & ~(m << 4)) >>> 4) | (x & m);
}
where ">>>" is an unsigned shift.
As a note, if 0 indicates the highest hex digit in a 32-bit word independent of the input, this is much simpler:
int remove(int x, int i) {
int m = 0xffffffff >>> (4*i);
return ((x & ~m) >>> 4) | (x & (m >>> 4));
}
Solution:
Replace operations using 10 with operations using 16.
Demo
Using Bitwise Operator:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
Using Math::pow:
public class Main {
public static void main(String[] args) {
int n = 0x12345;
int temp = n;
int length = 0;
// Find length
while (temp != 0) {
length++;
temp /= 16;
}
System.out.println("Length of the number: " + length);
// Remove digit at index 3
int m = n;
int index = 3;
for (int i = index + 1; i <= length; i++) {
m /= 16;
}
m *= ((int) (Math.pow(16, length - index - 1)));
m += n % ((int) (Math.pow(16, length - index - 1)));
System.out.println("The number after removing digit at index " + index + ": 0x" + Integer.toHexString(m));
}
}
Output:
Length of the number: 5
The number after removing digit at index 3: 0x1235
JavaScript version:
n = parseInt(12345, 16);
temp = n;
length = 0;
// Find length
while (temp != 0) {
length++;
temp = Math.floor(temp / 16);
}
console.log("Length of the number: " + length);
// Remove digit at index 3
m = n;
index = 3;
for (i = index + 1; i <= length; i++) {
m = Math.floor(m / 16);
}
m *= 1 << ((length - index - 1) << 2);
m += n % (1 << ((length - index - 1) << 2));
console.log("The number after removing digit at index " + index + ": 0x" + m.toString(16));
This works by writing a method to remove from the right but adjusting the parameter to remove from the left. The bonus is that a remove from the right is also available for use. This method uses longs to maximize the length of the hex value.
long n = 0x12DFABCA12L;
int r = 3;
System.out.println("Supplied value: " + Long.toHexString(n).toUpperCase());
n = removeNthFromTheRight(n, r);
System.out.printf("Counting %d from the right: %X%n", r, n);
n = 0x12DFABCA12L;
n = removeNthFromTheLeft(n, r);
System.out.printf("Counting %d from the left: %X%n", r, n);
Prints
Supplied value: 12DFABCA12
Counting 3 from the right: 12DFABA12
Counting 3 from the left: 12DABCA12
This works by recursively removing a digit from the end until just before the one you want to remove. Then remove that and return thru the call stack, rebuilding the number with the original values.
This method counts from the right.
public static long removeNthFromTheRight(long v, int n) {
if (v <= 0) {
throw new IllegalArgumentException("Not enough digits");
}
// save hex digit
long k = v % 16;
while (n > 0) {
// continue removing digit until one
// before the one you want to remove
return removeNthFromTheRight(v / 16, n - 1) * 16 + k;
}
if (n == 0) {
// and ignore that digit.
v /= 16;
}
return v;
}
This method counts from the left. It simply adjusts the value of n and then calls removeFromTheRight.
public static long removeNthFromTheLeft(long v, int n) {
ndigits = (67-Long.numberOfLeadingZeros(v))>>2;
// Now just call removeNthFromTheRight with modified paramaters.
return removeNthFromTheRight(v, ndigits - n - 1);
}
Here is my version using bit manipulation with explanation.
the highest set bit helps find the offset for the mask. For a long that bit is 64-the number of leading zeroes. To get the number of hex digits, one must divide by 4. To account for numbers evenly divisible by 4, it is necessary to add 3 before dividing. So that makes the number of digits:
digits = (67-Long.numberOfLeadingZeros(i))>>2;
which then requires it to be adjusted to mask the appropriate parts of the number.
offset = digits-i - 1
m is the mask to mask off the digit to be removed. So start with a -1L (all hex 'F') and right shift 4*(16-offset) bits. This will result in a mask that masks everything to the right of the digit to be removed.
Note: If offset is 0 the shift operator will be 64 and no bits will be shifted. To accommodate this, the shift operation is broken up into two operations.
Now simply mask off the low order bits
v & m
And the high order bits right shifted 4 bits to eliminate the desired digit.
(v>>>4)^ ~m
and then the two parts are simply OR'd together.
static long remove(long v, int i) {
int offset = ((67 - Long.numberOfLeadingZeros(v))>>2) - i - 1;
long m = (-1L >>> (4*(16 - offset) - 1)) >> 1;
return ((v >>> 4) & ~m) | (v & m);
}

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.

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.

Categories

Resources