如何有效地获得由最低有效非零位表示的数字

时间:2016-04-22 05:03:01

标签: c# bit-manipulation

例如,如果是0xc0,则结果为0x40, 由于0xc0等于二进制11000000,因此结果应为01000000。

public static byte Puzzle(byte x) {
    byte result = 0;
    byte[] masks = new byte[]{1,2,4,8,16,32,64,128};
    foreach(var mask in masks)
    {
      if((x&mask)!=0)
      {
        return mask;
      }
    }
    return 0;
}

这是我目前的解决方案。事实证明这个问题可以在3-4行中解决......

3 个答案:

答案 0 :(得分:2)

public static byte Puzzle(byte x) {
    return (byte) (x & (~x ^ -x));
}    

如果x是bbbb1000,~x是BBBB0111(B是!b)

-x实际上是~x + 1,(2的补码)所以在BBBB0111中加1是BBBB1000

~x ^ -x然后是00001111&用x给出最低的1位。

哈罗德在评论中提供了一个更好的答案

public static byte Puzzle(byte x) {
    return (byte) (x & -x);
}    

答案 1 :(得分:0)

Maby不是最佳解决方案,但您可以准备一个数组字节[256],存储每个数字的结果然后使用它。

一行中的另一种解决方案:

return (byte)((~(x | (x << 1) | (x << 2) | (x << 3) | (x << 4) | (x << 5) | (x << 6) | (x << 7) | (x << 8)) + 1) >> 1);

答案 2 :(得分:0)

几乎不是一线解决方案,但至少它不使用硬编码的位列表。

我会通过一些简单的位移来实现。基本上,将值向下移位直到最低位不为0,然后以执行的移位量向上移位1以重建最低有效值。因为它是'while',它需要提前零检查,否则它将在零上进入无限循环。

public static Byte Puzzle(Byte x)
{
    if (x == 0)
        return 0;
    byte shifts = 0;
    while ((x & 1) == 0)
    {
        shifts++;
        x = (Byte)(x >> 1);
    }
    return (Byte)(1 << shifts);
}