int howManyBits(int x) {
int concatenate;
int bias;
int sign = x >> 31; //get the sign
x = (sign & (~x)) | (~sign & x);
concatenate = (!!(x >> 16)) << 4;
concatenate |= (!!(x >> (concatenate + 8))) << 3;
concatenate |= (!!(x >> (concatenate + 4))) << 2;
concatenate |= (!!(x >> (concatenate + 2))) << 1;
concatenate |= x >> (concatenate + 1);
bias = !(x ^ 0);
return concatenate + 2 + (~bias + 1);
}
此代码用于计算表示2的补码中的整数n
所需的最小位数,假设int
数据类型用32位表示。假设右移是算术运算。
我知道基本方法是取n
的日志库2,将其四舍五入,然后添加1位以考虑符号位。
我也明白左移相当于乘以2而右移相当于除以2.
话虽如此,没有注释我无法解释这段代码在获取符号位值的部分之外的作用。我使用值为5的样本int
在铅笔和纸上完成了它 - 代码有效,但我不明白为什么。
有人可以提供代码正在做什么的直观细分吗?
答案 0 :(得分:4)
此代码可以使用一些注释。
如果它是正数,则保留x,如果是负数,则保留一个补码。这允许计算搜索最重要的一个,无论正面还是负面
x = (sign & (~x)) | (~sign & x);
我认为以下内容会更清楚:
x = sign ? ~x : x;
接下来是搜索使用二进制搜索完成的最高1位。首先搜索单词的上半部分。
concatenate = (!!(x >> 16)) << 4;
如果上半部分为1,则结果为16.后面的16作为答案的一部分使用,但也用于确定下一步搜索的位置。由于它在后面的班次中使用,因此将导致以下测试要么使用板的上半部分还是下半部分。
以下连接操作正在搜索原始数字逐渐变小的部分,看起来是所选择的16位的高8位或低8位中最重要的一位,然后是高4位或更低位选择的8位中的4位,依此类推。
concatenate |= (!!(x >> (concatenate + 8))) << 3; // Check which 8 bits
concatenate |= (!!(x >> (concatenate + 4))) << 2; // Check which 4 bits
concatenate |= (!!(x >> (concatenate + 2))) << 1; // Check which 2 bits
concatenate |= x >> (concatenate + 1); // Check which 1 bit
偏见只是检查数字是否为0。仅当x为0时才为1.我不理解对XOR运算符的需要。
最后将这些碎片加在一起。