谁能解释这个按位函数来计算 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(二元)卷积

操作符

谁能给我细细解释下无符号数和有符号数怎么表示,怎么输出,怎么进行转换,及其他相关内容

解释一下数学的log(对数)

C语言 10位的整数 按位取出来

如何计算该函数的增长率:T(n)= 2T(n ^(1/2))+ 2(n ^(1/2))