【问题标题】:Better algorithm for complementing integer value excluding the leading zero binary bits用于补充整数值的更好算法,不包括前导零二进制位
【发布时间】:2012-08-06 11:22:45
【问题描述】:

我将首先解释“补整数值不包括前导零二进制位”的含义(从现在开始,我将其称为非前导零位补码或 NLZ 补码)。

比如有整数92,二进制数是1011100。如果我们执行正常的按位非或补码,结果是:-93(有符号整数)或11111111111111111111111110100011(二进制)。那是因为前导零位也被补充了。

所以,对于 NLZ-Complement,前导零位不被补,那么 92 或 1011100 的 NLZ-complementing 的结果是:35 或 100011(二进制)。该操作是通过将输入值与非前导零值的 1 位序列进行异或运算来执行的。插图:

92:  1011100
     1111111 (xor)
     --------
     0100011 => 35


我做了这样的java算法:

public static int nonLeadingZeroComplement(int n) {
    if (n == 0) {
        return ~n;
    }
    if (n == 1) {
        return 0;
    }

    //This line is to find how much the non-leading zero (NLZ) bits count.
    //This operation is same like: ceil(log2(n))
    int binaryBitsCount = Integer.SIZE - Integer.numberOfLeadingZeros(n - 1);

    //We use the NLZ bits count to generate sequence of 1 bits as much as the NLZ bits count as complementer
    //by using shift left trick that equivalent to: 2 raised to power of binaryBitsCount.
    //1L is one value with Long literal that used here because there is possibility binaryBitsCount is 32
    //(if the input is -1 for example), thus it will produce 2^32 result whom value can't be contained in 
    //java signed int type.
    int oneBitsSequence = (int)((1L << binaryBitsCount) - 1);

    //XORing the input value with the sequence of 1 bits
    return n ^ oneBitsSequence;
}

我需要建议如何优化上述算法,尤其是生成 1 位补码序列 (oneBitsSequence) 的行,或者是否有人可以提出更好的算法?

更新:我也想知道这个非前导零补码的已知术语?

【问题讨论】:

  • 因此,对于所有 2 的幂,您都希望返回 0。因此,从 0 开始,序列将是 1, 0, 0, 0, 0, 2, 1, 0, 0, 6, .. .这有什么用?
  • 所谓的“NLZ-Complement”就是所谓的Ones' Complement。 en.wikipedia.org/wiki/One%27s_compliment
  • @MisterSmith:你确定吗?我认为不是。一个的补码也补充了前导零。
  • 在这种情况下,你是对的。将更新我的答案。
  • 经过一番思考,似乎您必须计算前导0。因此,我不会编辑我的错误答案,而是将其删除,因为第一个答案是正确的。

标签: java algorithm bit-manipulation complement


【解决方案1】:

你可以通过Integer.highestOneBit(i)方法得到最高的一位,左移一步,然后减1。这样你就得到了1s的正确长度:

private static int nonLeadingZeroComplement(int i) {
    int ones = (Integer.highestOneBit(i) << 1) - 1;
    return i ^ ones;
}

例如,

System.out.println(nonLeadingZeroComplement(92));

打印

35

【讨论】:

  • 我知道!必须有一个内置函数可以使这更简单。大声笑,你让这很容易。你知道这个 NLZ 补码的真实/已知术语吗?
  • @suud:不,抱歉,我不知道这个的特殊术语。
【解决方案2】:

显然@keppil 提供了最短的解决方案。另一种解决方案可能是这样的。

private static int integerComplement(int n){

  String binaryString = Integer.toBinaryString(n);

  String temp = "";
  for(char c: binaryString.toCharArray()){
      if(c == '1'){
          temp += "0";
      }
      else{
          temp += "1";
      }
  }
  int base = 2;
  int complement = Integer.parseInt(temp, base);

  return complement;
}

例如,

System.out.println(nonLeadingZeroComplement(92));

将答案打印为 35

【讨论】:

    猜你喜欢
    • 2011-08-31
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2017-03-16
    相关资源
    最近更新 更多