代码之家  ›  专栏  ›  技术社区  ›  JamesB41

得到最左边的一点

  •  2
  • JamesB41  · 技术社区  · 15 年前

    我有一个5位整数。在objective-c中是否有一个本地函数可以让我知道最左边的是哪个位?

    也就是说,我有01001,它会返回8或位置。

    谢谢

    9 回复  |  直到 12 年前
        1
  •  4
  •   Joost    15 年前
    NSInteger value = 9;
    NSInteger shift = 1;
    for(NSInteger bit = value; bit > 1; bit = value >> ++shift);
    NSInteger leftmostbit = 1 << shift;
    

    适用于每个位数。

        2
  •  7
  •   ChrisW    15 年前

    可以使用32个元素构建查阅表格:0、1、2、2、3等。

        3
  •  6
  •   Community CDub    8 年前

    这实际上与计算前导0的数目是相同的操作。有些CPU有这样的指令,否则您可以使用一些技巧,如 Hacker's Delight .

    它也相当于四舍五入到最接近的2次方,同样,您可以在 高效程序的奥秘 ,例如

    uint8_t flp2(uint8_t x)
    {
        x = x | (x >> 1);
        x = x | (x >> 2);
        x = x | (x >> 4);
        return x - (x >> 1);
    }
    

    参见: Previous power of 2

        4
  •  2
  •   Stephen Canon    15 年前

    如果您不想使用表查找,我将使用 31 - __builtin_clz(yourNumber) .

    __builtin_clz( ) 是由gcc、llvm gcc和clang(可能还有其他编译器)支持的编译器内部函数。它返回整数参数中前导零位的数目。从中减去 31 给出最高阶集合位的位置。它应该在任何目标体系结构上生成相当快的代码。

        5
  •  0
  •   Paul R    15 年前

    Stanford Bit Twiddling Hacks 有很多关于如何完成这一点的例子。

        6
  •  0
  •   Jakob Borg    15 年前

    如果您的意思是从右边第五位的任何位的值(五位值的“最左边”),那么:

        int value = 17;
        int bit = (value >> 4) & 1; // bit is 1
    

    如果您指的是最左边的1位的位置:

        int value = 2;
        int position;
        for (position = 0; position < 5; position++) {
                int bit = (value >> position) & 1;
                if (bit == 1)
                        break;
        }
        // position is 1
    

    最右边的位的位置是0,5位值的最左边的位是4,如果所有的位都为零,则为5。

    注意:这不是时钟周期中最有效的解决方案。希望这是一个相当清晰和有教育意义的计划。:)

        7
  •  0
  •   drawnonward    15 年前

    要清除最高有效位以下的所有位:

    while ( x & (x-1) ) x &= x - 1;
    // 01001 => 01000
    

    要清除最低有效位以上的所有位:

    x &= -x;
    // 01001 => 00001
    

    要获取字节中唯一设置位的位置,请执行以下操作:

    position = ((0x56374210>>(((((x)&-(x))*0x17)>>3)&0x1C))&0x07);
    // 01000 => 3
    

    在libkern.h中有一个 clz 函数定义为在32位int中计算前导零。这是最接近本机Objective-C函数的函数。要获取int中最高有效位的位置:

    position = 31 - clz( x );
    // 01001 => 3
    
        8
  •  0
  •   naivnomore    15 年前

    我不知道目标C,但这就是我在C中的方法。

    功率(2,int(log2(number))

    这应该为您提供最左边的1位值。

    在使用此解决方案之前,请参阅下面的StephenCanon评论。

        9
  •  0
  •   user411313    14 年前

    用VC++看一下 _ BitscanReverse/(64)英寸