Аналог битового поля на C#

357
26 ноября 2016, 18:57

Есть следующий код на C++:

#include <iostream>
using namespace std;
union
{
    unsigned short X;
    struct
    {  
        unsigned short param_01 :1; // DSL (младший бит числа X)
        unsigned short param_02 :1; // PPP
        unsigned short param_03 :1; // Link
        unsigned short param_04 :2; // битовое поле может содержать
        unsigned short param_05 :5; // более 1 бита
        unsigned short param_06 :1;
        unsigned short param_07 :1;
        unsigned short param_08 :2;
    } X_bit;
} Device;
int main()
{
    cin >> hex >> Device.X; // вводим число
    // Выводим результаты
    cout << Device.X_bit.param_01;
    cout << Device.X_bit.param_02;
    // и так далее
    return 0;
 }

Каким образом получить аналогичную функциональность на C#? Есть ли там битовые поля, а если нету, как лучше работать с такими данными?

Answer 1

Для вашего случая можно воспользоваться структурой BitVector32.

Для удобства, положим вот такой вспомогательный класс:

class SectionHelper
{
    BitVector32.Section? currSection = null;
    public BitVector32.Section AllocatedSection(int nbits)
    {
        // проверка
        if (nbits <= 0 || nbits > sizeof(short) * 8 - 1)
            throw new ArgumentException("wrong number of bits");
        var max = checked((short)((1 << nbits) - 1));
        currSection = currSection == null ?
                BitVector32.CreateSection(max) :
                BitVector32.CreateSection(max, currSection.Value);
        return currSection.Value;
    }
}

Пробуем:

class Program
{
    static void Main(string[] args)
    {
        // определяем битовые маски
        SectionHelper helper = new SectionHelper();
        var dsl_s      = helper.AllocatedSection(1);
        var ppp_s      = helper.AllocatedSection(1);
        var link_s     = helper.AllocatedSection(1);
        var param_04_s = helper.AllocatedSection(2);
        var param_05_s = helper.AllocatedSection(5);
        var param_06_s = helper.AllocatedSection(1);
        var param_07_s = helper.AllocatedSection(1);
        var param_08_s = helper.AllocatedSection(2);
        // пользуемся
        var bv = new BitVector32(0x341a);
        Console.WriteLine(bv[dsl_s]);
        Console.WriteLine(bv[ppp_s]);
        Console.WriteLine(bv[link_s]);
        Console.WriteLine(bv[param_04_s]);
        Console.WriteLine(bv[param_05_s]);
        Console.WriteLine(bv[param_06_s]);
        Console.WriteLine(bv[param_07_s]);
        Console.WriteLine(bv[param_08_s]);
        Console.WriteLine();
        bv = new BitVector32(0xcbe5);
        Console.WriteLine(bv[dsl_s]);
        Console.WriteLine(bv[ppp_s]);
        Console.WriteLine(bv[link_s]);
        Console.WriteLine(bv[param_04_s]);
        Console.WriteLine(bv[param_05_s]);
        Console.WriteLine(bv[param_06_s]);
        Console.WriteLine(bv[param_07_s]);
        Console.WriteLine(bv[param_08_s]);
    }
}
READ ALSO
Погрешность std::chrono::steady_clock

Погрешность std::chrono::steady_clock

Мне необходимо каждый час выполнять какие то действияСоздаю что то типа таймера с помощью std::chrono::steady_clock, в while проверяю или пришло время выполнять...

271
Готовые решения GUI - наподобие Steam/Origin

Готовые решения GUI - наподобие Steam/Origin

Подскажите где можно найти готовые решения(С исходным кодом) с модерн дизайном интерфейса, как это делают в Steam/Origin

325
Диалоговое окно С++

Диалоговое окно С++

Написать программу, которая при нажатии клавиши ESC выводит окно-диалог о необходимости завершения программыВ окне диалога выводятся два...

463
Подключение библиотек C++

Подключение библиотек C++

Решил добавить gtest к решениюСоздал проект для тестов, подключил в него gtest

266