查找二进制数的二进制组合



对C#来说非常陌生,所以这可能是一个愚蠢的问题。

我正在使用很多UInt64。这些表示为十六进制,对吧?如果我们查看它的二进制表示,我们是否可以返回这样一个数组,如果我们应用"or"操作,我们将返回原始 UInt64?

例如,假设

x = 1011

然后,我正在寻找一种有效的方法来到达,

f(x) = {1000, 0010, 0001}

这些数字是十六进制,而不是二进制。对不起,我也是十六进制的新手。

我已经有方法了,但感觉效率低下。我首先转换为二进制字符串,然后遍历该字符串以找到每个"1"。然后,我将相应的二进制数添加到数组中。

有什么想法吗?

这是一个更好的例子。我有一个十六进制数x,形式为,

UInt64 x = 0x00000000000000FF

其中 x 的二进制表示为

0000000000000000000000000000000000000000000000000000000011111111

我希望找到一个由十六进制数字 (UInt64??( 组成的数组,以便应用于该数组所有成员的 or 操作将再次产生 x。例如

f(x) = {0x0000000000000080, // 00000....10000000
0x0000000000000040, // 00000....01000000
0x0000000000000020, // 00000....00100000
0x0000000000000010, // 00000....00010000
0x0000000000000008, // 00000....00001000
0x0000000000000004, // 00000....00000100
0x0000000000000002, // 00000....00000010
0x0000000000000001  // 00000....00000001
}

我认为问题归结为找到一种有效的方法来找到二进制扩展中"1"的索引......

public static UInt64[] findOccupiedSquares(UInt64 pieces){
UInt64[] toReturn = new UInt64[BitOperations.PopCount(pieces)];
if (BitOperations.PopCount(pieces) == 1){
toReturn[0] = pieces;
}
else{
int i = 0;
int index = 0;
while (pieces != 0){
i += 1;
pieces = pieces >> 1;
if (BitOperations.TrailingZeroCount(pieces) == 0){ // One
int rank = (int)(i / 8);
int file = i - (rank * 8);
toReturn[index] = LUTable.MaskRank[rank] & LUTable.MaskFile[file];
index += 1;
}
}
}
return toReturn;
}

你的问题仍然让我感到困惑,因为你似乎混淆了数字和数字表示的概念。 即有一个整数,然后有一个该整数的十六进制表示。

您可以非常简单地将任何整数分解为其以 base-2 为基数的分量。

ulong input = 16094009876; // example input
ulong x = 1;
var bits = new List<ulong>();
do
{
if ((input & x) == x)
{
bits.Add(x);
}
x <<= 1;
} while (x != 0);

bits现在是一个整数列表,每个整数表示输入中的二进制1位之一。这可以通过添加(或 ORing - 相同的东西(所有值来验证。所以这个表达是正确的:

bits.Aggregate((a, b) => a | b) == input

如果你想在列表中使用这些整数的十六进制表示形式,你可以简单地使用ToString()

var hexBits = bits.Select(b => b.ToString("X16"));

如果你想要整数的二进制表示,你可以使用Convert

var binaryBits = bits.Select(b => Convert.ToString((long)b, 2).PadLeft(64, '0'));

相关内容

  • 没有找到相关文章

最新更新