谁能解释这个按位函数来计算 log(n)
Posted
技术标签:
【中文标题】谁能解释这个按位函数来计算 log(n)【英文标题】:Can anyone explain this bitwise function to compute log(n) 【发布时间】:2015-06-22 07:40:20 【问题描述】: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
的log base 2,四舍五入,然后加上1位来占符号位。
我也明白左移相当于乘以 2,右移相当于除以 2。
话虽如此,如果没有 cmets,除了获取符号位值的部分之外,我无法破译这段代码在做什么。我在铅笔和纸上用一个值为 5 的样本 int
完成了它 - 代码有效,但我不明白为什么。
有人可以提供一些代码在做什么的直观细分吗?
【问题讨论】:
【参考方案1】:此代码可以使用一些 cmets。
如果 x 为正数,则保留原样,如果为负数,则取反码。这允许计算搜索最重要的一个,无论是正面还是负面
x = (sign & (~x)) | (~sign & x);
我认为以下内容会更清楚:
x = sign ? ~x : x;
接下来是使用二分搜索完成最高 1 位的搜索。首先搜索单词的上半部分。
concatenate = (!!(x >> 16)) << 4;
如果上半部分为 1,则结果为 16。稍后将使用 16 作为答案的一部分,也用于确定接下来要搜索的位置。由于它用于随后的班次,因此将导致以下测试要么在电路板的上半部分完成,要么在下半部分完成。
以下连接操作在逐渐减小的原始数字中进行搜索选择的 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 运算符。
最后将各个部分加在一起。
【讨论】:
以上是关于谁能解释这个按位函数来计算 log(n)的主要内容,如果未能解决你的问题,请参考以下文章
如何计算时间复杂度为 O(n log n) 的 XOR(二元)卷积