表示在java语言中使用二进制的整数

时间:2011-08-19 00:25:02

标签: java implementation bit-manipulation

问题在于:

你有2个32位数字,N& M和两位位置,i&学家写一个方法来设置i和j之间的所有位在N中等于M(例如,M成为位于i的N的子串 并从j)开始

例如:   输入:   int N = 10000000000,M = 10101,i = 2,j = 6;   输出:     int N = 10001010100

我的解决方案:

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)

问题:     实现算法的方便数据类型是什么?例如    我们在C中有int n = 0x100000,因此我们可以在n上应用按位运算符。    在Java中,我们有BitSet类,它有清晰的set方法,但不支持    左/右移位算子;如果我们使用int,它支持左/右移位,但是    没有二进制表示(我不是在谈论二进制字符串表示)    实现这个的最佳方法是什么?

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);   
}        

3 个答案:

答案 0 :(得分:3)

逐位运算符|&^~以及十六进制文字(0x1010)都可用于java

如果该约束保持int将是有效数据类型,则32位数为int

顺便说一句

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

是一个稍微清晰的面具构造

答案 1 :(得分:0)

Java int拥有您需要的所有操作。我并不完全理解你的问题(现在太累了),所以我不会给你一个完整的答案,只是一些提示。 (如果需要,我稍后会修改它。)

  • 以下是j行:(1 << j)-1
  • 以下是j行,其后是i零:((1 << j) - 1) << i
  • 这是一个位掩码,用于屏蔽x j中间的x & ~(((1 << j) - 1) << i)位置。

尝试使用Integer.toBinaryString()查看结果。 (它们也可能对负值或太大的值给出奇怪的结果。)

答案 2 :(得分:0)

我认为你误解了Java是如何工作的。所有值都表示为引擎盖下的“一系列位”,其中包含整数和长整数。

根据您的问题,一个粗略的解决方案是:

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;
}

我的假设是:

  • iN中设置的最右侧(最不重要)位。
  • M最右边的位从右侧映射到N的{​​{1}}位。
  • 过早的优化是万恶之源 - 这就是O(j-i)。如果您使用复杂的掩码,就像在问题中那样,可以在O(1)中进行,但它不会像可读的那样可读,并且可读代码在97%的时间比有效代码更重要。