Jacxx Ответов: 3

Представление списка/массива целых чисел в 64 - битном массиве


У меня есть список/массив с некоторыми целыми числами.
массив = {1,2,3,4,5,7,11,14,15...}
для каждого целого числа, существующего в массиве/списке от 1 до 8, я добавляю бит до 1 байта, а затем преобразую двоичный код в десятичный. В этом случае 11111010(6 и 8 не существует) = 250. Аналогично следующая итерация.

Что я уже пробовал:

Я попробовал это сделать, добавив каждый бит к строке, когда число встречается, а затем преобразовав его в десятичное число. Как только все 8 итераций будут выполнены, преобразуйте их в 8-байтовый массив.
Есть ли лучший способ сделать это? возможно, с помощью побитовых операторов?

private byte[] GetBitMapFromFields(List<int> fieldNo)
        {
            byte[] bytes = new byte[8];
            List<int> tempList = new List<int>();
            string binaryfield = string.Empty;
            var count = 1;
            for (var i = 0; i < fieldNo.Count; i++)
            {
                var k = 0;
                for(var j =1; j<=8;j++)
                {
                    if (count == fieldNo[i])
                    {
                        binaryfield = binaryfield + 1;
                        i++;
                        k++;
                        count++;
                    }
                    else
                    {
                        binaryfield = binaryfield + 0;
                        k++;
                        count++;
                    }
                    if(k==8)
                    {
                        i--;
                        break;
                    }
                }
                int output = Convert.ToInt32(binaryfield, 2);
                binaryfield = string.Empty;
                tempList.Add(output);

            }
            bytes = ConvertListToByte(tempList); //Converts the list to byte array of length 8
            return bytes;
        }

3 Ответов

Рейтинг:
8

Patrice T

Ваш код для установки битов выглядит довольно сложным.
Прежде всего, вам нужно знать, что целое число хранится в базе 2, целое число-это поле битов.
пример 10!

10= 1*2^3+0*2^2+1*2^1+0*2^0

биты нумеруются справа налево, начиная с бита 0, а число соответствует степеням 2 из предыдущей формулы.
bit numbers: 7 6 5 4 3 2 1 0
Values:                    ^ = 1 = 2^0
                         ^ = 2 = 2^1
                       ^ = 4 = 2^2
                      ^ = 8 = 2^3
...
              ^ = 128 = 2^7
10 is         0 0 0 0 1 0 1 0

Чтобы установить старшие биты в 8 битах, вам просто нужно использовать знание их значений и знать побитовые операции.
один цикл делает свое дело:
int set8bits (int value) { // set high bits
    int bit= 128;
    for ( int i=7, i>=0, i--) {
        if (value & bit) { // is true when bit is already set
            break;
        }
        value = value | bit; // set bit
        bit= bit >> 1 // move next bit
    }
    return value;
}


Jacxx

Большое спасибо за объяснение, Патрис. Это было решение, которое я искал. Теперь я проверяю, лучше ли работает этот ответ или ответ Джорджа.

Patrice T

Если вопрос решен, примите полезные решения, это закроет вопрос.

Patrice T

Мое решение должно быть более эффективным, потому что оно позволяет избежать трансформаций.

Рейтинг:
2

George Swan

Я сделал нечто подобное при шифровании данных с помощью BitArray класс. Надеюсь, это вам поможет


static void Main(string[] args)
       {
           List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 7 };//, 11, 14, 15
           int max = numbers.Max();
           int mod8 = max % 8;
           int length = mod8 == 0 ? max : max + 8 - mod8;
           BitArray bits = new BitArray(length);
           foreach (var n in numbers) bits[length - n] = true;
           int[] tempIntArray = new int[1];
           bits.CopyTo(tempIntArray, 0);
           int result = tempIntArray[0];

           Console.ReadLine();
       }


Jacxx

Спасибо, Джордж, это решение действительно сработало. Однако вместо int[] я преобразовал биты непосредственно в байт[] -
byte[] byteArray = новый байт[(int)Math.Потолочные (двойные)биты.Длина / 8)];
биты.CopyTo(byteArray, 0);
Кроме того, пришлось повернуть его вспять.

Рейтинг:
0

Richard MacCutchan

Что-то вроде следующего будет захватывать восемь битов одновременно:

int pattern = 0;

for ( // expression to iterate over your list
{
    if ( // if the value exists
    {
        pattern |= 1;
    }
    pattern <<= 1;
}

// pattern now contains the mask of the items.

Вам также нужно разорвать петлю после 8 тестовых заданий. В качестве альтернативы вы можете захватить 32 или 64 бита одновременно.