C# Битовый сдвиг и побитовые операции

Я пытаюсь найти более быстрый подход к следующей проблеме.

У меня есть 2 массива int, представляющих биты, вот пример 8-позиционного

int[] intArray1 = new[] {1, 1, 1, 0, 1, 1, 0, 1};
int[] intArray2 = new[] {0, 1, 0, 0, 1, 0, 0, 1};

Количество бит в массивах может быть 8, 32, 64 и 64+.

Таким образом, я должен иметь возможность создать алгоритм, который обрабатывает любой тип ввода, сдвигает биты для каждого и применяет логические операции между обоими массивами наиболее быстрым способом.

После небольшого исследования я подумал о преобразовании массива int в массив bool и создании BitArray с использованием массива bool, потому что BitArray имеет конструктор, который поддерживает bools как биты, и имеет встроенные побитовые операции.

bool[] boolArray = intArray.Select(s => s.Equals(1)).ToArray();
BitArray bitArray = new BitArray(boolArray);

Однако он не поддерживает встроенный битовый сдвиг, его нужно выполнять итеративно, теряя всю точку производительности, которую я пытаюсь достичь.

Я мог бы использовать int32 и int64, но это решение не будет работать для размеров более 64 бит.

С уважением

BitArray довольно неуклюжий. По уважительной причине, это также непросто сделать эффективным для процессора. Он теряет 64 бита, и только ассемблерный код может сделать его лучше, который не может быть сгенерирован с помощью MSIL. Просто погуглите "C# bitarray shift" для обращений, сомнительно, что они будут сильно отличаться от того, что у вас есть.

Hans Passant 02.08.2018 18:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
709
1

Ответы 1

Почему бы просто не использовать BigInteger?

Вы можете использовать этот метод для преобразования string в BigInteger:

public static BigInteger BinToDec(string value)
{
    // BigInteger can be found in the System.Numerics dll
    BigInteger res = 0;

    // I'm totally skipping error handling here
    foreach(char c in value)
    {
        res <<= 1;
        res += c == '1' ? 1 : 0;
    }

    return res;
}

Или, если вы хотите придерживаться своего массива int и преобразовать его в BigInteger:

public static BigInteger BitArrayToBigDecimal(int[] bitIntArr) {
    // BigInteger can be found in the System.Numerics dll
    BigInteger res = 0;

    // I'm totally skipping error handling here
    foreach(int i in bitIntArr) {
        res <<= 1;
        res += i == 1 ? 1 : 0;
    }
    return res;
}

Их тоже можно немного сдвинуть. Как это:

var foo = BinToDec("11101101");

BigInteger fooShifted = foo >> 4;

var bar = BitArrayToBigDecimal(new[] {1, 1, 1, 0, 1, 1, 0, 1});

BigInteger barShifted = bar >> 4;

Дайте знать, если у вас появятся вопросы.

ему нужно обрабатывать более 64-битные входы, biginteger - 64 бита

MrVoid 02.08.2018 23:11

@MrVoid BigInteger динамично растет. Из Документы MSDN: BigInteger «Представляет произвольно большое целое число со знаком». Теоретически он может быть бесконечно большим, но он ограничен размером объекта .NET (около 2 ГБ).

agillgilla 02.08.2018 23:16

Другие вопросы по теме