Установка битов в байтовом массиве с использованием C # - PullRequest
1 голос
/ 14 сентября 2011

У меня есть байтовый массив из 32 байтов, где первые 4 бита каждого байта (от 0 до 3) представляют собой установленное или неустановленное состояние числа от 1 до 128. Например, если мне дано число 3, янужно установить бит 2 в первом байте в массиве.Если мне дано число 9, мне нужно установить бит 0 третьего байта в массиве.Проблема в том, что я нашел разумный способ сделать это в C #.Я уверен, что должен быть простой способ сделать это математически, но до сих пор не удалось найти метод.Пока я почесал голову над этим, я подумал, что увижу, может кто-нибудь дать какой-нибудь совет.

--------- Обновление -------------------

На основании полученных ответов я произвел следующую функцию.Это именно то, что мне нужно.Возможно, я не ясно дал понять в своем вопросе, что мне нужно, но мне дали достаточно советов, чтобы найти правильный код.

// outputNumber = number passed into this function

byte[] bytes = new byte[32];

int bit = (outputNumber - 1) % 4;

byte byteSetting = (byte)(1 << bit);

bytes[(outputNumber - 1) / 4] |= byteSetting;

Ответы [ 3 ]

2 голосов
/ 14 сентября 2011

Вы можете установить биты в каждом байте в массиве следующим образом:

array[2] |= (byte)(1<<3); // set bit #4 / index 3 in array element #3 / index 2

Вы можете очистить немного так:

array[2] &= unchecked((byte)(~(1<<3))); // clear the same bit we set previously
2 голосов
/ 14 сентября 2011
int byt = bitNumber / 4; // You could do byt = bitNumber >> 2
int bit = bitNumber % 4; // You could do bit = bitNumber & 3

bytes[byt] |= (byte)(1 << bit);

Где bytes - ваш байтовый массив.

Для сброса:

bytes[byt] &= (byte)(byte.MaxValue ^ (1 << bit));

Чтобы прочитать значение байта:

var res = bytes[byt] & (byte)(1 << bit)

(если вам интересно, ^ является оператором xor)

1 голос
/ 14 сентября 2011

Нужно что-то подобное. В 64-битной системе вместо байтов используйте ulongs (32 bit -> uint). Разница в производительности довольно значительная.

public struct BitField {

    private ulong[] _Values;

    private BitField(ulong[] values) {
        _Values = values;
    }

    public static BitField New() {
        return new BitField(new ulong[] { 0ul, 0ul });
    }

    public BitField Clone() {
        return new BitField(new ulong[] { _Values[0], _Values[1] });
    }

    public void Clear() {
        _Values[0] = ulong.MinValue;
        _Values[1] = ulong.MinValue;
    }

    public void SetAll() {
        _Values[0] = ulong.MaxValue;
        _Values[1] = ulong.MaxValue;
    }

    public void AND_Combine(BitField bitField) {

        _Values[0] &= bitField._Values[0];
        _Values[1] &= bitField._Values[1];
    }

    public void OR_Combine(BitField bitField) {

        _Values[0] |= bitField._Values[0];
        _Values[1] |= bitField._Values[1];
    }

    public bool Intersects(BitField bitField) {

        if ((_Values[0] & bitField._Values[0]) > 0) {
            return true;
        }
        else {
            if ((_Values[1] & bitField._Values[1]) > 0) {
                return true;
            }
            else {
                return false;                                   
            }
        }
    }

    public bool this[int index] {
        get {
            if (index > 127 || index < 0) {
                return false;
            }
            int item = index >> 6;
            int bit = index % 64;

            ulong compare = 1ul << bit;
            return ((_Values[item] & compare) == compare);
        }
        set {
            if (index >= 0 || index < 128) {
                int item = index >> 6;
                int bit = index % 64;
                ulong compare = 1ul << bit;

                if (value) {
                    _Values[item] |= compare;
                }
                else {
                    _Values[item] &= ~compare;
                }
            }
        }
    }
}
...