none
как сделать Shift (побитовый сдвиг) для BitArray? RRS feed

  • Вопрос

  • нужен быстрый способ для побитового сдвигам BitArray

    сейчас сделал в лоб (циклический сдвиг - младшие биты переносятся на место сдвинутых старших битов), но это медленно

    using System.Collections; //BitArray gamma_value = new BitArray(длина массива); byte[] gamma = { 1, 1, 1 }; //какой-то массив байт BitArray gamma_value = new BitArray(gamma); //переводим массив байт в массив бит #region сдвиг на 1 бит на право ">>" (бит который вытесняется переносится с права на лево) bool c = gamma_value[0]; //младший бит for (int i_bit = 1; i_bit < gamma_value.Count; i_bit++) { gamma_value[i_bit - 1] = gamma_value[i_bit]; } gamma_value[gamma_value.Count - 1] = c; //с - значение старшего бита #endregion gamma_value.CopyTo(gamma, 0); //переводим массив бит в массив байт // gamma = { 128, 128, 128 };

    т.е. вот что произошло

    00000001 00000001 00000001
    10000000 10000000 10000000

    есть в .Net какой-то способ сделать побитовый сдвиг быстрее и короче?

    тот же вопрос и для циклического сдвига (хотя, меня обычных битовый сдвиг интересует сейчас)
    • Изменено sg6336 16 августа 2014 г. 11:55
    16 августа 2014 г. 10:27

Ответы

Все ответы

  • В общем, нашел один вариант, который в два раза быстрее работает чем тот что привел в начале

    #region сдвиг на 1 бит
    
    int len = gamma_value.Length; //длина массива бит
    c = gamma_value[0]; //младший бит
    
    //создание массива типа bool 
    //такой же длины как gamma_value типа BitArray
    bool[] gamma_new = new bool[len]; 
    
    //копируем массив типа BitArray в массив типа bool
    gamma_value.CopyTo(gamma_new, 0); 
    
    //копируем массив bool со сдвигом на 1ну позицию в другой массив bool
    Array.Copy(gamma_new, 1, gamma_new, 0, len - 1); 
    
    //замена последнего элемента массива bool
    gamma_new[len - 1] = c; 
    
    //преобразование массива типа bool в массив типа BitArray
    gamma_value = new BitArray(gamma_new); 
    
    #endregion

    идею взял от сюда Is there any simple way to concatenate two BitArray (C# .NET)?

    может все же у BitArray есть возможность побитового сдвига или копирования одного BitArray в другой BitArray кусками?

    • Изменено sg6336 16 августа 2014 г. 20:00
    16 августа 2014 г. 18:02
  • Вопрос - для чего это нужно?
    В ассемблере сдвигом вправо или влево я ускорял
    умножение или деление целого числа на 2 - это оправдано.
    Тем более, что там была соответствующая аппаратно исполняемая команда.
    Если же у Вас массив битов является стеком каких-либо индикаторов
    типа FIFO - первым пришел - первым вышел,
    то лучше ничего не сдвигать,
    а при переполнении перезаписывать биты, начиная с начального -
    несложная логика и быстрое исполнение.

    17 августа 2014 г. 8:32
  • мне нужно запрограммировать стохастический сдвиг (для реализации криптографического примитива). Может с помощью небезопасного кода можно сделать побитовый сдвиг более быстрым? Вы сказали про ассемблер. В С++ можно делать ассемблерные вставки, а в С# разве можно? Если можно, то скажите как.
    18 августа 2014 г. 14:46
  • Обычно Cpp модули упаковываются в DLL,
    а потом исполняются в C#.
    Как будет здесь - не знаю, надо пробовать.
    Чисто ассемблером занимался очень давно,
    и это был совсем другой ассемблер и совсем другие системы.
    Но наверняка все стандартные операции есть и здесь.

    19 августа 2014 г. 3:20
  • В ассемблере сдвигом вправо или влево я ускорял 
    умножение или деление целого числа на 2 - это оправдано.

    Добрый день,

    операция умножения выполняется намного дольше, чем побитовый сдвиг (asm shl, shr). Именно поэтому операцию умножения или деления на 2 заменяют побитовым сдвигом!

    19 августа 2014 г. 4:06
  • Вот хорошее руководство по использованию ассемблерного кода в c#

    Using Unmanaged code and assembler in C#

    19 августа 2014 г. 4:15
  • спасибо, попробую с ассемблером в C# разобраться.
    19 августа 2014 г. 7:55