Задать вопрос
@Xiran

Что не так с кодом, проверяющим логическую схему?

Дана логическая схема:
6559a19fab70c317955659.png
Задача состоит в том, чтобы посчитать сколько вариантов значений входных переменных при которых на ее выходе истина существует.
Я написал код:
#include <cstddef>
#include <bitset>
#include <iostream>

constexpr std::size_t INPUT_BITS_COUNT { 5 };
constexpr std::size_t VARIANTS_COUNT { 32 }; 

enum {
    A = 0,
    B = 1,
    C = 2,
    D = 3,
    E = 4
};

bool check(const std::bitset<INPUT_BITS_COUNT> &bitset) {
    const auto bOrD { bitset[B] | bitset[D] };

    const auto cAndE { bitset[C] & bitset[E] };

    const auto aOrBod { bitset[A] | bOrD };

    const auto notEOrBod { ~(bitset[E] | bOrD) };

    const auto caeAndAob { cAndE & aOrBod };

    return caeAndAob | notEOrBod;
}

int main() {
    std::bitset<INPUT_BITS_COUNT> inputBits;

    inputBits.reset();

    std::size_t counter { 0 };

    for (std::size_t i { 0 }; i <= VARIANTS_COUNT; i++) {
        inputBits = i;

        if (check(inputBits))
            counter++;
    }

    std::cout << counter;
}

Поясню: в первой строке цикла i побитово копируется в inputBits,
и безопасность такого копирования гарантируется тем, что i не больше 32 (11111 в двоичной системе счисления).

Функция check почему-то всегда возвращает true (может и нет),
поэтому программа выводит 33,
что неверно.
  • Вопрос задан
  • 111 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Во-первых, у вас цикл от 0 до 32 включительно. Т.е. вы на последней, 33-ей итерации пытаетесь преобразовать 0b100000 в bitset, фактически, второй раз учитывая вариант со всеми нолями. Вот почему вы получаете 33 а не 32.

Во-вторых, у вас ошибка с тем, что вы из bitmask берете биты, которые есть числа 0 и 1 и проводите над ними битовые операции, а не логические. И это у вас там 32-битные числа же! Для | и & оно еще совпадает с вашими ожиданиями, а вот ~ обращает ВСЕ 32 бита числа.

Поэтому ~(bitset[E] | bOrD) всегда выдаст или -1 или -2. Вы потом это пропустите через or, получите опять же -1 или -2 и в конце преобразуете это в bool. И вот тут-то оно всегда и станет true.

Чтобы это исправить, или используйте логические операции (||, &&, !), или вместо ~x используйте x^1, или в самом конце возвращайте результат с &1, чтобы значения остальных бит ни на что не влияли.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы