Я использую инструкции в этом ответе, чтобы получить и установить битовые значения 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
Итак, как мне получить, если в выражениях используются битовые выражения?
(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);
}
Ну, да, вы можете использовать любое значение в значениях if, а значения, не равные нулю, считаются истинными.
Но как вы можете сказать, что делает весь этот код, выходит за меня. Шансы на это с ошибкой высоки.
Я бы предложил написать некоторые отдельные функции для чтения/очистки/установки определенного бита в вашем массиве. Тогда должно стать яснее, что вы делаете.
Кстати, если это c-код, вы не должны бросать результат calloc. Если, с другой стороны, это C++ код, вы не должны использовать C-style cast.
((k-3)/2)/(sizeof(char)*8)
выражение в функцию или макрос, тогда вам будет проще увидеть, что вы делаете, а также как следует будет проще как читать, так и писать код. Выражение также может быть несколько упрощено, так какsizeof(char)
задан так, чтобы всегда возвращать1
.