Совершенно новый для C#, так что это может быть глупый вопрос.
Я работаю со многими UInt64. Они выражаются как шестнадцатеричные, верно? Если мы посмотрим на его двоичное представление, можем ли мы вернуть такой массив, к которому, если мы применим операцию 'или', мы вернемся к исходному UInt64?
Например, скажем
x = 1011
Тогда я ищу эффективный способ прийти к
f(x) = {1000, 0010, 0001}
Где эти числа находятся в шестнадцатеричном, а не двоичном формате. Извините, я тоже новичок в hex.
У меня уже есть метод, но он кажется неэффективным. Сначала я конвертирую в двоичную строку и l oop поверх этой строки, чтобы найти каждую «1». Затем я добавляю соответствующее двоичное число в массив.
Есть мысли?
Вот лучший пример. У меня есть шестнадцатеричное число x в виде
UInt64 x = 0x00000000000000FF
Где двоичное представление x
0000000000000000000000000000000000000000000000000000000011111111
I wi sh, чтобы найти массив, состоящий из шестнадцатеричных чисел (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;
}