用于补充整数值的更好算法,不包括前导零二进制位

nul*_*ull 1 java algorithm bit-manipulation complement

我将首先解释我的意思是"补充不包括前导零二进制位的整数值"(从现在开始,为简洁起见,我将其称为非前导零位补码或NLZ补码).

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

因此,对于NLZ补码,前导零位不补充,那么NLZ补充92或1011100的结果是:35或100011(二进制).通过将输入值与非前导零值的1位序列进行异或来执行操作.插图:

92:  1011100
     1111111 (xor)
     --------
     0100011 => 35
Run Code Online (Sandbox Code Playgroud)


我做了这样的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;
}
Run Code Online (Sandbox Code Playgroud)

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

更新:我也想知道这个非领先的零补充的已知术语?

Kep*_*pil 9

您可以通过该Integer.highestOneBit(i)方法获得最高的一位,向左移动一步,然后减去1.这将获得正确的1s 长度:

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

例如,

System.out.println(nonLeadingZeroComplement(92));
Run Code Online (Sandbox Code Playgroud)

版画

35
Run Code Online (Sandbox Code Playgroud)