Как использовать биты для выражения оператора управления?

0

Я использую инструкции в этом ответе, чтобы получить и установить битовые значения char. У установки и получения нет/не должно быть никаких проблем (семантически то же, что и связанный ответ).

Проблема в том, что я не могу правильно использовать значения бит из нее в управляющих операторах (if).

Соответствующий фрагмент кода, в котором я столкнулся с проблемой:

unsigned long int find_container(unsigned long int k){
  return (k)/(sizeof(char)*8);
}

unsigned long int find_bit(unsigned long int k){
  return (k)%(sizeof(char)*8);
}

....
if (~(marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))){
  printf("must print\n");
}
marks[find_container((k-3)/2)] |= 1<<find_bit((k-3)/2);

if (~(marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))){
  printf("this shouldn't have been printed\n");
}
....

Печать:

должен печатать

это не должно было быть напечатано

Очевидно, что оператор if не принимает выражения битовых значений.

Ну, я попробовал лить значение бита в bool (~(bool)((marks[find_container((k-3)/2)] >> (find_bit((k-3)/2)&1))), но он didn Не изменяйте это поведение.

Первоначально все значения в массиве marks устанавливаются равными нулю

marks = (char *)calloc( chars, (sizeof(char)));

chars - unsigned long int

Итак, как мне получить, если в выражениях используются битовые выражения?

  • 2
    Я рекомендую вам поместить целое ((k-3)/2)/(sizeof(char)*8) выражение в функцию или макрос, тогда вам будет проще увидеть, что вы делаете, а также как следует будет проще как читать, так и писать код. Выражение также может быть несколько упрощено, так как sizeof(char) задан так, чтобы всегда возвращать 1 .
  • 1
    Этот код ... замечательно. Вы пишете на C или C ++? Выбери один.
Показать ещё 11 комментариев
Теги:

2 ответа

1
Лучший ответ
(find_bit((k-3)/2)&1)

либо 0, либо 1.

Я думаю, что вы упустили свои круглые скобки и что вы ищете

(marks[find_container((k-3)/2)] >> find_bit((k-3)/2)) & 1

Я бы рекомендовал вам добавить функции абстрагирования для управления битами, что делает код более читаемым и менее подверженным ошибкам.
Что-то вроде этого.

// No safety, for clarity
void set(unsigned long int* bits, size_t which)
{
   bits[find_container(which)] |= 1 << find_bit(which);
}

bool get(unsigned long int* bits, size_t which)
{
   return (bits[find_container(which)] >> find_bit(which)) & 1;
}

// example
if (!get(marks, k))
{
    set(marks, k);
}
0

Ну, да, вы можете использовать любое значение в значениях if, а значения, не равные нулю, считаются истинными.

Но как вы можете сказать, что делает весь этот код, выходит за меня. Шансы на это с ошибкой высоки.

Я бы предложил написать некоторые отдельные функции для чтения/очистки/установки определенного бита в вашем массиве. Тогда должно стать яснее, что вы делаете.

Кстати, если это c-код, вы не должны бросать результат calloc. Если, с другой стороны, это C++ код, вы не должны использовать C-style cast.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню