2010-09-10 4 views
6

У меня есть массив System.Collections.BitArray (~ 3000 элементов), и я хотел бы сдвинуть все биты влево на 1. Однако коллекция, похоже, не поддерживает эту операцию (например, bitArray < < 1 не работает и нет способа). Любая идея о том, как это сделать?BitArray - бит сдвига

Спасибо!

ответ

4

Этот простой сниппет показывает ручной способ его выполнения. Значение bitArray[0] переписывается:

//... bitArray is the BitArray instance 

for (int i = 1; i < bitArray.Count; i++) 
{ 
    bitArray[i - 1] = bitArray[i]; 
} 

bitArray[bitArray.Count - 1] = false // or true, whatever you want to shift in 

Создание этого метода расширение не должно быть большое дело.

+2

Это замечательно ... но медленно. Я бы предпочел бы специальный оператор или метод, так как мы играем с битами. – Martin

+0

Вы можете пройти длинный путь копирования содержимого из вашего 'BitArray' в' bool [] 'и скопировать данные в другой' bool [] 'с помощью смещений. Наконец, вы можете воссоздать свой «битаррей» из результирующего 'bool []'. Но я сомневаюсь, что это будет быстрее, чем доступ к каждому элементу для ваших ~ 3000 бит. –

0

Самый простой способ, с помощью которого я мог бы перейти от верхней части головы, - преобразовать BitArray в BigInt или подобную структуру, которая поддерживает побитовое смещение и назад. Теперь встроенный встроенный BigInteger в .Net 4 не поддерживает сдвиг, я думаю, но есть и другие, которые делают, например, реализацию Mono.

2

System.Numerics.BigInteger действительно поддерживает смещение бит.

+1

С одной оговоркой: «В отличие от побитовой операции с левым сдвигом с целыми примитивами метод LeftShift сохраняет знак исходного значения BigInteger». Итак, (-3 << 30)! = ((BigInteger) (- 3) << 30) – FarmerBob

+0

И причина этого - это тип BigInteger. – detay

1

Я не знаю, как об эффективности, но этот метод расширения делает работу

public static BitArray ShiftRight(this BitArray instance) 
{ 
    return new BitArray(new bool[] { false }.Concat(instance.Cast<bool>().Take(instance.Length - 1)).ToArray()); 
} 
+1

ОП попросил сдвиг влево. Мне понравилось это, так что вот левая версия сдвига: return new BitArray ( (instance.Cast () .Take (instance.Length - 1) .ToArray()). Concat (new bool [] {newState}) .ToArray() ); – xgo

+0

Действительно. Благодаря :) – eye

0

Recreate BitArray себя в качестве обертки вокруг ulong[]; реализация битовых сдвигов числом, меньшим 64, является куском торта таким образом, и потребуется меньше времени и убить меньше белых медведей, чем другие предложенные подходы. Опаляясь «бит, который упадет до конца», если вы хотите их сохранить, вам, возможно, придется вырастить массив (или нет, если они равны нулю, и вы говорите, что несуществующий элемент неявно удерживает ноль).

Смежные вопросы