Какой самый простой способ подмножества «всех остальных битов» в C / C ?

#c

#c

Вопрос:

Например,

 unsigned char a = 0b11010010;
  

Я хочу подмножество a для каждого кусочки и положить их вместе, чтобы сделать четыре-битное значение, то есть, принимая 0 , 2 , 4 , 6 ю позицию и поместить их в 0 , 1 , 2 , 3 ю позицию.

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

 unsigned char subset =  (a amp; (1 << 0))       |
                       ((a amp; (1 << 2)) >> 1) |
                       ((a amp; (1 << 4)) >> 2) |
                       ((a amp; (1 << 6)) >> 3);
  

Я хочу знать, есть ли более простой или элегантный способ сделать это.

Комментарии:

1. 3-й? Третий? Это выглядит неправильно 🙂

2. О, да… Спасибо. Исправлено.

3. Что ж, без проблем. Но я хочу знать, делаю ли я что-то вроде «изобретения колеса» или делаю несколько неэффективно (с точки зрения читаемости или производительности).

4. на самом деле вы не можете подмножествовать биты, потому что они не адресуемы. альтернативой является использование массива из 8 символов, а затем маскирование, сохраняющее каждое битовое значение в виде одного байта

Ответ №1:

Имеющийся у вас код является наиболее четким выражением вашего намерения и наиболее поддается любой возможной оптимизации компилятора (и вы могли бы объявить его как функцию constexpr ).). Вы могли бы сделать какую-нибудь хитрую маскировку и умножение на магические числа — но я даже не собираюсь выводить эти числа, потому что выигрыш перевешивается невозможностью поддержки!

Ответ №2:

Определенно не элегантно и расширилось бы до того, что вы только что написали, но мы же не можем ненавидеть шаблоны, не так ли?

 template <int pos = 0>
struct altbit{
  static char compute(char a) {
    return ((a amp; (1 << (2*pos))) >> pos) | altbit<pos 1>::compute(a);
  }
};

template <>
struct altbit<4> {
  static char compute (char a) {
    return 0;
  }
};
  

Использование: altbit<>::compute(a)

Комментарии:

1. constexpr кто-нибудь?

Ответ №3:

Использование std::bitset может сделать битовые операции более элегантными:

 #include <iostream>
#include <bitset>

int main()
{
    std::bitset<8> b1(0b11010010);
    std::bitset<4> b2;
    for (int i = 0; i < 4;   i)
    {
        b2[i] = b1[i*2];
    }
    std::cout << std::hex << "in: " << b1 << ", out: " << b2 << "n";
}