Три логических значения, сохраненные в одном tinyint - PullRequest
0 голосов
/ 01 октября 2009

вероятно, простой вопрос, но я, кажется, страдаю от блока программиста. :)

У меня есть три логических значения: A, B и C. Я хотел бы сохранить комбинацию состояний в виде крошечного знака без знака (максимум 255) в базе данных и иметь возможность получать состояния из сохраненного целого числа. Несмотря на ограниченное количество комбинаций, я бы хотел избежать жесткого кодирования каждой комбинации состояний к определенному значению (например, если A = true и B = true имеет значение 1).

Я пытался присвоить значения переменным таким образом (A = 1, B = 2, C = 3) и затем добавить, но я не могу отличить A и B от истинных, то есть только C, являющихся истинными.

Я в тупике, но почти уверен, что это возможно. Спасибо

Ответы [ 4 ]

5 голосов
/ 01 октября 2009

Бинарная математика, я думаю. Выберите место, которое является степенью 2 (1, 2, 4, 8 etch), затем вы можете использовать оператор «bitwise and» & для определения значения. Скажите А = 1, В = 2, С = 4

00000111 => A B и C => 7

00000101 => А и С => 5

00000100 => C => 4

затем определить их:

if( val  & 4 ) // same as if (C)
if( val  & 2 ) // same as if (B)
if( val  & 1 ) // same as if (A)

if((val  & 4) && (val & 2)  ) // same as if (C and B)

Нет необходимости в таблице состояний.

Редактировать: отразить комментарий Если tinyint имеет максимальное значение 255 =>, у вас есть 8 битов для игры и вы можете хранить там 8 логических значений

1 голос
/ 01 октября 2009

Я добавлю, что вы должны найти способ не использовать магические числа . Вы можете встроить маски в константы, используя Left Logical / Bit Shift с постоянной битовой позицией, которая является позицией интересующего флага в битовом поле. (Ух ты ... это почти бессмысленно.) Примером на C ++ будет:

enum Flags {
    kBitMask_A = (1 << 0),
    kBitMask_B = (1 << 1),
    kBitMask_C = (1 << 2),
};

uint8_t byte = 0;        //          byte = 0b00000000
byte |= kBitMask_A;      // Set A,   byte = 0b00000001
byte |= kBitMask_C;      // Set C,   byte = 0b00000101
if (byte & kBitMask_A) { // Test A,  (0b00000101 & 0b00000001) = T
    byte &= ~kBitMask_A; // Clear A, byte = 0b00000100
}

В любом случае, я бы порекомендовал поискать поддержку Bitset на вашем любимом языке программирования. Многие языки абстрагируют логические операции от обычных арифметических операций или операций «тест / набор».

1 голос
/ 01 октября 2009

двоичная математика, как говорили другие

кодировка:

myTinyInt = A*1 + B*2 + C*4 (assuming you convert A,B,C to 0 or 1 beforehand)

декодирование

bool A = myTinyInt & 1 != 0 (& is the bitwise and operator in many languages)
bool B = myTinyInt & 2 != 0
bool C = myTinyInt & 4 != 0
0 голосов
/ 01 октября 2009

Нужно использовать двоичный файл ...

A = 1, B = 2, С = 4, D = 8, Е = 16, F = 32, G = 64, H = 128

Это означает, что A + B = 3, но C = 4. У вас никогда не будет двух конфликтующих значений. Я перечислил максимум, который вы можете иметь для одного байта, 8 значений или (бит).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...