简体   繁体   中英

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 (eg 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 int s 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 i th bit from the right.
  • That premature optimization is the root of all evil - this is O(ji). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM