如何有效地获取最低有效非零位表示的数字
How to get the number represented by least-significant non-zero bit efficiently
例如,如果是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行就可以解决了...
可能不是最好的解决方案,但是你可以准备一个字节数组[256],存储每个数字的结果然后使用它。
1 行中的另一个解决方案:
return (byte)((~(x | (x << 1) | (x << 2) | (x << 3) | (x << 4) | (x << 5) | (x << 6) | (x << 7) | (x << 8)) + 1) >> 1);
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);
}
几乎不是单行解决方案,但至少它不使用位的硬编码列表。
我会通过一些简单的位移来完成。基本上,将值向下移位直到最低位不为 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);
}
例如,如果是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行就可以解决了...
可能不是最好的解决方案,但是你可以准备一个字节数组[256],存储每个数字的结果然后使用它。
1 行中的另一个解决方案:
return (byte)((~(x | (x << 1) | (x << 2) | (x << 3) | (x << 4) | (x << 5) | (x << 6) | (x << 7) | (x << 8)) + 1) >> 1);
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);
}
几乎不是单行解决方案,但至少它不使用位的硬编码列表。
我会通过一些简单的位移来完成。基本上,将值向下移位直到最低位不为 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);
}