增加位大小的有效条件

发布于 2024-10-07 05:12:59 字数 415 浏览 3 评论 0原文

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

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

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

同样,任何使用特殊 cpu 操作码计算前导零位数的东西(好得多,但仍然不是很好)。

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

Suppose I have an increasing sequence of unsigned integers C[i]. As they increase, it's likely that they will occupy increasingly many bits. I'm looking for an efficient conditional, based purely on two consecutive elements of the sequence C[i] and C[i+1] (past and future ones are not observable), that will evaluate to true either exactly or approximately once for every time the number of bits required increases.

An obvious (but slow) choice of conditional is:

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

and likewise anything that computes the number of leading zero bits using special cpu opcodes (much better but still not great).

I suspect there may be a nice solution involving an expression using just bitwise or and bitwise and on the values C[i+1] and C[i]. Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

無處可尋 2024-10-14 05:12:59

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

所以

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

Suppose your two numbers are x and y. If they have the same high order bit, then x^y is less than both x and y. Otherwise, it is higher than one of the two.

So

v = x^y
if (v > x || v > y) { ...one more bit... }
瑶笙 2024-10-14 05:12:59

我认为你只需要 clz(C[i+1]) clz(C[i+1]) clz(C[i+1]) clz(C[i+1]) clz(C[i]) 其中 clz 是一个返回前导零数量的函数(“计数前导零”)。某些 CPU 系列具有用于此目的的指令(可以作为内在指令使用)。如果没有,那么您必须自己动手(通常只需要一些说明) - 请参阅 黑客的乐趣

I think you just need clz(C[i+1]) < clz(C[i]) where clz is a function which returns the number of leading zeroes ("count leading zeroes"). Some CPU families have an instruction for this (which may be available as an instrinsic). If not then you have to roll your own (it typically only takes a few instructions) - see Hacker's Delight.

千秋岁 2024-10-14 05:12:59

鉴于(我相信这来自 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])

Given (I believe this comes from 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);
}

Your conditional is simply hibit(C[i]) != hibit(C[i+1]).

彩扇题诗 2024-10-14 05:12:59

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 上)并进行比较。

BSR - Bit Scan Reverse (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

You need two of these (on C[i] and C[i]+1) and a compare.

神爱温柔 2024-10-14 05:12:59

Keith Randall 的解决方案很好,但是您可以通过使用以下代码来节省一条异或指令,该代码在 O(w + n) 条指令中处理整个序列,其中 w 是字中的位数,n 是元素的数量在序列中。如果序列很长,则大多数迭代将仅涉及一次比较,从而避免一条异或指令。

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

t = 1; // original setting

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

Keith Randall's solution is good, but you can save one xor instruction by using the following code which processes the entire sequence in O(w + n) instructions, where w is the number of bits in a word, and n is the number of elements in the sequence. If the sequence is long, most iterations will only involve one comparison, avoiding one xor instruction.

This is accomplished by tracking the highest power of two that has been reached as follows:

t = 1; // original setting

if (c[i + 1] >= t) {
  do {
    t <<= 1;
  } while (c[i + 1] >= t); // watch for overflow
  ... // conditional code here
}
2024-10-14 05:12:59

当值大约溢出 2 的幂时,位数会增加。那么一个简单的测试是,该值是否等于 2 的负 1 次方?这可以通过询问来完成:

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

The number of bits goes up when the value is about overflow a power of two. A simple test is then, is the value equal to a power of two, minus 1? This can be accomplished by asking:

if  ((C[i] & (C[i]+1))==0) ...
独闯女儿国 2024-10-14 05:12:59

当值即将溢出 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 ;
   }

The number of bits goes up when the value is about to overflow a power of two.
A simple test is then:

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

If you want it even faster:

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 ;
   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文