简体   繁体   English

用Java语言中的二进制表示整数

[英]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. 您将获得2个32位数字N和M,以及两个位置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) 编写一种方法来将N中i和j之间的所有位设置为等于M(例如,在位于i处并从j开始时,M成为N的子串)

For example: input: int N = 10000000000, M = 10101, i = 2, j = 6; 例如:输入:int N = 10000000000,M = 10101,i = 2,j = 6; output: int N = 10001010100 输出: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. 例如,我们在C中具有int n = 0x100000,因此我们可以在n上应用按位运算符。 in Java, we have BitSet class, it has clear, set method, but doesnt support left/right shift operator; 在Java中,我们有BitSet类,它具有清晰的set方法,但不支持左/右移位运算符; 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? 如果我们使用int,则它支持左/右移位,但是没有二进制表示(我不是在谈论二进制字符串表示),实现此目的的最佳方法是什么?

Code in java (after reading all comments): Java中的代码(阅读所有注释后):

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 &^~以及十六进制文字( 0x1010 )在Java中都可用

32 bit numbers are int s if that constraint remains int will be a valid data type 如果该约束保持不变,则int 32位数字int将是有效的数据类型

btw 顺便说一句

mask = (-1<<j)|(-1>>>(32-i));

is a slightly clearer construction of the mask 是面罩的结构稍微清晰一点

Java's int has all the operations you need. Java的int具有您所需的所有操作。 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 . 这是连续的j个: (1 << j)-1
  • Here are j ones in a row, followed by i zeros: ((1 << j) - 1) << i . 这是连续j个,后跟i零: ((1 << j) - 1) << i
  • Here is a bitmask which masks out j positions in the middle of x: x & ~(((1 << j) - 1) << i) . 这是一个位掩码,它屏蔽了x中间的j位置: x & ~(((1 << j) - 1) << i)

Try these with Integer.toBinaryString() to see the results. 尝试使用Integer.toBinaryString()查看结果。 (They might also give strange results for negative or too big values.) (对于负值或太大的值,它们也可能给出奇怪的结果。)

I think you're misunderstanding how Java works. 我认为您误解了Java的工作原理。 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 . iN中设置的最右边(最低有效)位。
  • M 's right-most bit maps to N 's i th bit from the right. M的最右边的位从右边映射到N的第i位。
  • That premature optimization is the root of all evil - this is O(ji). 过早的优化是万恶之源-这就是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. 如果像问题中那样使用复杂的掩码,则可以在O(1)中进行操作,但是它的可读性不高,可读代码比有效代码重要的时间是97%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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