Work a Bitwise operation backwards - java

I need to know how to do this backwards so that it will work for all of the options. If I start with shift i can get radix so How would i get shift from starting with radix.
int shift = 4; //3 will give octal base 4 will give Hex base 1 will give binary base
int radix = 1 << shift; // this comes out as 16
So Like i said above how would i get this to go the otherway
int radix = 16;
int shift =(some operation);
Also to make this work for if radix is 8, 2 or 16

There's lots of useful methods in the Integer class. Try
int shift = Integer.numberOfTrailingZeros(radix).

Try with this method,
public static int radixToShift(int radix){
int shift = 0;
for(int i=0;radix >> i >1;i++){
shift++;
}
return shift;
}
Code
int shift = 4;
int radix = 1 << shift;
System.out.println("Radix :: "+radix);
System.out.println("Shift :: "+radixToShift(radix));
Output
Radix :: 16
Shift :: 4

Related

Bit manipulation insertion

class UpdateBits
{
// Function to updateBits M insert to N.
static int updateBits(int n, int m, int i, int j)
{
/* Create a mask to clear bits i through j
in n. EXAMPLE: i = 2, j = 4. Result
should be 11100011. For simplicity, we'll
use just 8 bits for the example. */
int allOnes = ~0; // will equal sequence of all ls
// ls before position j, then 0s. left = 11100000
int left= allOnes << (j + 1);
// l's after position i. right = 00000011
int right = ((1 << i) - 1);
// All ls, except for 0s between i and j. mask 11100011
int mask = left | right;
/* Clear bits j through i then put min there */
// Clear bits j through i.
int n_cleared = n & mask;
// Move m into correct position.
int m_shifted = m << i;
// OR them, and we're done!
return (n_cleared | m_shifted);
}
public static void main (String[] args)
{
// in Binary N= 10000000000
int n = 1024;
// in Binary M= 10011
int m = 19;
int i = 2, j = 6;
System.out.println(updateBits(n,m,i,j));
}
}
I am unable to understand this line:
int right = ((1 << i) - 1);
1 << i means you shift the 1 i bits to the left. If i is 2, this would result in the bits being 00000100. No matter the i, we would always have exactly one 1 in there, followed by i zeros.
Now you take that minus 1 and get 00000011. If you are familiar with binary you should see that taking a binary number that has exactly one 1 in it minus 1 will always result in a binary number that has some zeros and then ones (regex: 0*1*).
So in total you get a number that has exactly i bits as 1 at the end.

Bit shift of signed byte strange behaviour

I have written a function to print the bit out in a byte. This happens by setting the most significant bit to 1 comparing it to the inputbyte and if it is also 1 printing "1" else "0". The comparison byte is then shifted right.
How do I achieve starting with 10000000 and shifting to 01000000 then 00100000...
I believe my problem is caused by promotion to int then recasting but I don't see the solution.
package errorreporting;
public class ErrorReporting {
ErrorReporting() {
}
public static void main(String[] args) {
ErrorReporting myError = new ErrorReporting();
byte myByte = 16;
myError.printByteArray(myByte);
}
public void printByteArray(byte inputByte) {
// print out 1 or 0
byte comparison = -128;
for (int x = 0; x < 8; x++) {
if ((inputByte & comparison) != 0) {
System.out.print("1");
} else {
System.out.print("0");
}
// System.out.print(" comparison : " + comparison);
comparison = (byte) (comparison >>> 1);
}
System.out.println(" : " + inputByte);
}
}
This post has some info : Java bitshift strangeness
I believe my problem is caused by promotion to int then recasting
Yes, it is a combination of some implicit and explicit casting and sign extension:
All arguments are first promoted to int before the shift operation takes place, see also https://stackoverflow.com/a/3948303/1611055
Due to 1., your unsigned shift operator >>> does not help - it correctly shifts a 0 into the leftmost position, but since the source argument -128 has been promoted to int before the shift is applied (resulting in 0xffffff80), you end up with 0x7fffffc0 after the first shift.
The simplest solution is to use an int for your mask:
int comparison = 0x80; // -128;
Theoretically, you could also still use a byte for the mask, but then you need to explicitly convert it to an int while discarding the sign bit at the same time, before applying the shift operator, like this:
byte comparison = -128;
...
comparison = (byte)( (((int) comparison) & 0xff) >>> 1);
((int) comparison) & 0xff) assumes that the byte should really be "unsigned" and converts it to the corresponding "unsigned" int value. Then, you can apply the shift operator (>> or >>> does not matter, since we have a positive int value in any case) and cast it back to a byte.

Java - Bit Insertion

I have a long number like:
long l = Long.parseLong("10*000001111110" , 2) ;
Now, I want to add two bits in one position (say 2nd position, marked as *) into the long number.
Like,
long l = Long.parseLong("10*11*000001111110" , 2) ; (given between *)
Can anybody help me how to do that ? Note that I give an example to illustrate what I want. In real, I have only long land I have to work on it.
Edit:
1) position is not constant may be 0, 1 , 2 .. whatever.
2) and msb's can be 0. Means,
long l = Long.parseLong("00000010*000001111110" , 2) ;
long l = Long.parseLong("00000010*11*000001111110" , 2) ;
It sounds like you want something like bitStuffing where masking (&, ~, ^, and |) and shifting (>> and <<) are your instruments of choice.
long insertBit(long p_orignal, long p_new_bits, int p_starting_position_from_right, int p_ending_position_from_right)
{
long returnValue = p_original;
long onlyNewBits = 0;
// Set the bit to zero
long mask = (0xFFFFFFFFFFFFFFFFl);
for (int i=p_starting_position_from_right; i<=p_ending_position_from_right; i++)
{
mask ^ (1l << i);
}
returnValue = returnValue & mask;
mask = ~mask;
onlyNewBits = ~(p_new_bits & mask);
returnValue |= onlyNewBits;
return returnValue;
}
Disclaimer: I don't have a Java compiler available to compile this, but it should be something like this.
The first idea I had is the following:
Extract the first x bits that needs to stay on the position they are (in your example: 10) -> you could do this by running through a loop which creates the appropriate bitmask:
long bitmask = 1;
for(long bit = 1; bit < index; bit++) {
bitmask = (bitmask << 1) | 1;
}
Now you can create the long number that gets inserted -> just shift that number index positions to the left.
After that, you can easily build the new number:
long number = (((oldNumber >> index) << index) << insertionLength) | (insertion << index) | (oldNumber && bitmask);
Note: ((oldNumber >> index) << index) clears out the right part of the number (this part gets appended at the end using the bistmask). then you just need to shift this result by the length of the insertion (make space for it) and or it with the insertion (this needs to get shifted to the left by the index where to insert: (insertion << index). Finally, or the last part of the number (extracted via the bitmask: oldNumber && bitmask) to this result and you are done.
Note: I haven't tested this code. However, generally it should work but you may need to check my shifts (either it is index or index - 1 or so)!
If you only have the Long value say 123 you need to first convert this to a binary string. Like so:
String binaryValue = Long.toBinaryString("123L");
Then we take the string representation and perform a manipulation a specific character like so:
char[] characters = binaryValue.toCharArray();
char desiredCharacter = characters[index];
if(desiredCharacter == '1')
{
if(newValue == '1')
{
desiredCharacter = '0';
}
}else{
if(newValue == '1')
{
desiredCharacter ='1';
}
}
finally we convert the modified characters back into a string like so:
String rebuiltString = new String(characters);
I am sure there are more efficient ways to do this.
Well, if you want to set a specific bit in a number:
To turn it on:
number |= (1 << pos)
if pos = 4: (1<<pos) = 00000000 00000000 00000000 00010000
To turn it off:
number &= ~(1 << pos)
if pos = 4: ~(1<<pos) = 11111111 11111111 11111111 11101111
where pos is the position of the bit (with 0 being the low order bit, and 64 being the high order bit).

Java results differ for (int)Math.pow(2,x) and 1<<x

Why do the following two operations yield different results in Java for x = 31 or 32 but the same results for x=3?
int x=3;
int b = (int) Math.pow(2,x);
int c = 1<<x;
Results:
x=32: b=2147483647; c=1;
x=31: b=2147483647; c=-2147483648;
x=3: b=8 ; c=8
There are multiple issues at play:
An int can only store values between -2147483648 and 2147483647.
1 << x only uses the lowest five bits of x. Thus, 1 << 32 is by definition the same as 1 << 0.
Shift operations are performed on the two's-complement integer representation of the value of the left operand; this explains why 1 << 31 is negative.
Math.pow(2, 32) returns a double.
(int)(d), where d is a double greater than 2147483647 returns 2147483647 ("the largest representable value of type int").
What this interview question does is show that (int)Math.pow(2, x) and 1 << x are not equivalent for values of x outside the 0...30 range.
P.S. It is perhaps interesting to note that using long in place of int (and 1L in place of 1) would give yet another set of results different from the other two. This holds even if the final results are converted to int.
According to the documentation Math.pow will promote both of its arguments to double and return double. Obviously when the returned result is double and you cast it to int you'll get only the highest 32 bits and the rest will be truncated - hence you always get the (int) Math.pow(2,x); value. When you do bitshift you always work with ints and hence an overflow occurs.
Consider the limits of the type int. How large a number can it hold?
Here's a micro-benchmark for the case of a long. On my laptop (2.8GHz), using shift instead of Math.pow is over 7x faster.
int limit = 50_000_000;
#Test
public void testPower() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = (long)Math.pow(2,p);
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 3.758 s
}
#Test
public void testShift() {
Random r = new Random(7);
long t = System.currentTimeMillis();
for (int i = 0; i < limit; i++) {
int p = r.nextInt(63);
long l = 1L << p;
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t)/1000.0); // 0.523 s
}
int is 32 bits in size and since it is signed (by default), the first bit is used for the sign. When you shift left 31 bits, you get the Two's Compliment, which is -(2^32). When you shift left 32 bits, it just loops all the way back around to 1. If you were to do this shifting with longs instead of ints, you would get the answers you expect (that is until you shift 63+ bits).

represent an integer using binary in java language

Here is the problem:
You're given 2 32-bit numbers, N & M, and two bit positions, i & j. write a method to set all bits between i and j in N equal to M (e.g. M becomes a substring of N at locating at i
and starting at j)
For example:
input:
int N = 10000000000, M = 10101, i = 2, j = 6;
output:
int N = 10001010100
My solution:
step 1: compose one mask to clear sets from i to j in N
mask= ( ( ( ((1<<(31-j))-1) << (j-i+1) ) + 1 ) << i ) - 1
for the example, we have
mask= 11...10000011
step 2:
(N & mask) | (M<<i)
Question:
what is the convenient data type to implement the algorithm? for example
we have int n = 0x100000 in C, so that we can apply bitwise operators on n.
in Java, we have BitSet class, it has clear, set method, but doesnt support
left/right shift operator; if we use int, it supports left/right shift, but
doesnt have binary representation (I am not talking about binary string representation)
what is the best way to implement this?
Code in java (after reading all comments):
int x = Integer.parseInt("10000000000",2);
int x = Integer.parseInt("10101",2);
int i = 2, j = 6;
public static int F(int x, int y, int i, int j){
int mask = (-1<<(j+1)) | (-1>>>(32-i));
return (mask & x ) | (y<<i);
}
the bit-wise operators |, &, ^ and ~ and the hex literal (0x1010) are all available in java
32 bit numbers are ints if that constraint remains int will be a valid data type
btw
mask = (-1<<j)|(-1>>>(32-i));
is a slightly clearer construction of the mask
Java's int has all the operations you need. I did not totally understand your question (too tired now), so I'll not give you a complete answer, just some hints. (I'll revise it later, if needed.)
Here are j ones in a row: (1 << j)-1.
Here are j ones in a row, followed by i zeros: ((1 << j) - 1) << i.
Here is a bitmask which masks out j positions in the middle of x: x & ~(((1 << j) - 1) << i).
Try these with Integer.toBinaryString() to see the results. (They might also give strange results for negative or too big values.)
I think you're misunderstanding how Java works. All values are represented as 'a series of bits' under the hood, ints and longs are included in that.
Based on your question, a rough solution is:
public static int applyBits(int N, int M, int i, int j) {
M = M << i; // Will truncate left-most bits if too big
// Assuming j > i
for(int loopVar = i; loopVar < j; loopVar++) {
int bitToApply = 1 << loopVar;
// Set the bit in N to 0
N = N & ~bitToApply;
// Apply the bit if M has it set.
N = (M & bitToApply) | N;
}
return N;
}
My assumptions are:
i is the right-most (least-significant) bit that is being set in N.
M's right-most bit maps to N's ith bit from the right.
That premature optimization is the root of all evil - this is O(j-i). If you used a complicated mask like you did in the question you can do it in O(1), but it won't be as readable, and readable code is 97% of the time more important than efficient code.

Categories