用于增加位大小的有效条件

时间:2010-12-10 17:45:56

标签: c algorithm bit-manipulation

假设我有一个递增的无符号整数序列C[i]。随着它们的增加,它们可能会占据越来越多的位。我正在寻找一个有效的条件,纯粹基于序列C[i]C[i+1]的两个连续元素(过去和未来的元素是不可观察的),它们将精确或近似地评估为真每次所需的位数增加。

条件的明显(但缓慢)选择是:

if (ceil(log(C[i+1])) > ceil(log(C[i]))) ...

同样可以使用特殊的cpu操作码来计算前导零位的数量(更好但仍然不是很好)。

我怀疑可能有一个很好的解决方案涉及一个表达式,只使用按位或按位并且值C[i+1]C[i]。有什么想法吗?

7 个答案:

答案 0 :(得分:16)

假设您的两个数字是x和y。如果它们具有相同的高阶位,则x ^ y小于x和y。否则,它高于两者中的一个。

所以

v = x^y
if (v > x || v > y) { ...one more bit... }

答案 1 :(得分:2)

我认为你只需要clz(C[i+1]) < clz(C[i])其中clz是一个函数,它返回前导零的数量(“计数前导零”)。一些CPU系列有一个指令(可能作为一个内在的可用)。如果没有,那么您必须自己动手(通常只需要几条指示) - 请参阅Hacker's Delight

答案 2 :(得分:0)

当值大约溢出2时,位数会增加。那么一个简单的测试就是,这个值等于2的幂,减1?这可以通过询问:

来完成
if  ((C[i] & (C[i]+1))==0) ...

答案 3 :(得分:0)

鉴于(我认为这来自Hacker's Delight):

int hibit(unsigned int n) {
    n |= (n >>  1);
    n |= (n >>  2);
    n |= (n >>  4);
    n |= (n >>  8);
    n |= (n >> 16);
    return n - (n >> 1);
}

您的条件只是hibit(C[i]) != hibit(C[i+1])

答案 4 :(得分:0)

BSR - 位扫描反转(386 +)

    Usage:  BSR     dest,src
    Modifies flags: ZF

    Scans source operand for first bit set.  Sets ZF if a bit is found
    set and loads the destination with an index to first set bit.  Clears
    ZF is no bits are found set.  BSF scans forward across bit pattern
    (0-n) while BSR scans in reverse (n-0).

                             Clocks                 Size
    Operands         808x  286   386   486          Bytes

    reg,reg           -     -   10+3n  6-103          3
    reg,mem           -     -   10+3n  7-104         3-7
    reg32,reg32       -     -   10+3n  6-103         3-7
    reg32,mem32       -     -   10+3n  7-104         3-7

你需要其中两个(在C [i]和C [i] +1上)和比较。

答案 5 :(得分:0)

Keith Randall的解决方案很好,但您可以使用以下代码保存一条xor指令,该代码在O(w + n)指令中处理整个序列,其中w是一个字中的位数,n是序列中的元素数量。如果序列很长,大多数迭代只涉及一次比较,避免一个xor指令。

这是通过跟踪已达到的两个最高功率来完成的,如下所示:

t = 1; // original setting

if (c[i + 1] >= t) {
  do {
    t <<= 1;
  } while (c[i + 1] >= t); // watch for overflow
  ... // conditional code here
}

答案 6 :(得分:-1)

当值即将溢出2的幂时,位数会增加。 那么一个简单的测试就是:

 while (C[i] >= (1<<number_of_bits)) then number_of_bits++;

如果你想要更快:

int number_of_bits = 1;
int  two_to_number_of_bits = 1<<number_of_bits ;


... your code ....

while ( C[i]>=two_to_number_of_bits )
   { number_of_bits++; 
     two_to_number_of_bits = 1<<number_of_bits ;
   }