Как перевести эти шестнадцатеричные числа в побитовые значения? - PullRequest
0 голосов
/ 09 сентября 2011

Я просматриваю исходный код проекта, написанного на C. Вот список опций, которые определены (нет, это не реальные определения ... не очень описательные!)

...
#define OPTION_5    32768
#define OPTION_6    65536
#define OPTION_7    0x20000L
#define OPTION_8    0x40000L
#define OPTION_9    0x80000L

Я бы хотел добавить новую опцию OPTION_10, но прежде чем я это сделаю, я бы хотел понять, что именно представляют собой шестнадцатеричные числа?

Преобразуют ли эти числа в ожидаемые десятичные значения 131 072 262 144 524 288? Если так, то почему бы не сохранить тот же формат, что и у предыдущих вариантов?

Ответы [ 5 ]

3 голосов
/ 09 сентября 2011

Преобразуют ли эти числа в ожидаемые десятичные значения 131,072

Да. Вы можете использовать Google для конвертации: поиск " 0x20000 в десятичном виде ".

Если это так, то почему бы не сохранить тот же формат, что и у предыдущих параметров?

Полагаю, просто потому, что программисты знают свои способности от двух до 65536 и предпочитают шестнадцатеричное, где они более узнаваемы, выше этого.

Суффикс L заставляет буквальную константу быть набранной, по крайней мере, как long int, , но выбранный тип может быть еще больше, если необходимо держать константу . Это, вероятно, не нужно в вашей программе, и программист использовал его, потому что он / она не понимал выделенное предложение. Подробные сведения приведены в 6.4.4.1, стр. 56 стандарта C99.

2 голосов
/ 09 сентября 2011

Еще одна мысль, чтобы добавить к существующим ответам, я предпочитаю определять такие флаги, как это:

enum {
    OPTION_5_SHIFT = 15,
    OPTION_6_SHIFT,
    OPTION_7_SHIFT,
    OPTION_8_SHIFT,
    OPTION_9_SHIFT,
    OPTION_10_SHIFT
};

enum {
    OPTION_5 = 1L << OPTION_5_SHIFT,
    OPTION_6 = 1L << OPTION_6_SHIFT,
    OPTION_7 = 1L << OPTION_7_SHIFT,
    OPTION_8 = 1L << OPTION_8_SHIFT,
    OPTION_9 = 1L << OPTION_9_SHIFT,
    OPTION_10 = 1L << OPTION_10_SHIFT
};

Это позволяет избежать явно вычисленных констант и значительно упрощает вставку / удаление значений,и т.д.

0 голосов
/ 09 сентября 2011

Конкретные значения представляют опции флага битов, которые можно комбинировать с побитовым оператором ИЛИ |:

flags = (OPTION_5|OPTION_6);

Из двоичного представления этих значений вы увидите, что у каждого есть один уникальный битустановить, чтобы разрешить их объединение с помощью побитового ИЛИ:

0x8000L   = 32768   = 00000000 00000000  10000000 00000000
0x10000L  = 65536   = 00000000 00000001  00000000 00000000
0x20000L  = 131072  = 00000000 00000010  00000000 00000000
0x40000L  = 262144  = 00000000 00000100  00000000 00000000
0x80000L  = 524288  = 00000000 00001000  00000000 00000000
0x100000L = 1048576 = 00000000 00010000  00000000 00000000

Чтобы узнать, установлен ли флаг в переменной flags, вы можете использовать побитовый оператор AND &:

if(flags & OPTION_6)
{
    /* OPTION_6 is active */
}
0 голосов
/ 09 сентября 2011

Они представляют собой одинаковые числа, все они являются степенями двойки.Или тоже посмотрите на это с другой точки зрения, все они представляют собой двоичные числа, имеющие ровно одно целое (не предназначенное для phun).

Одна из возможных причин, по которой они написаны такими, какие они есть (даже если причина неХорошим является то, что многие программисты знают следующую последовательность по Харту:

1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536

Эта последовательность соответствует первым 17 степеням двух.Тогда все уже не так просто, поэтому они, вероятно, переключились на гекс (слишком ленив, чтобы изменить все предыдущие числа).

0 голосов
/ 09 сентября 2011

Каждая цифра числа представляет коэффициент умножения базы числовой системы числа на степень позиции цифры в числе, отсчитываемую справа налево, начиная с нуля.

Итак, 32768 = 8 *10 ^ 0 + 6 * 10 ^ 1 + 7 * 10 ^ 2 + 2 * 10 ^ 3 + 3 * 10 ^ 4.

(подсказка для полноты: x ^ 0 = 1, x ^ 1 = x.)

Шестнадцатеричные числа имеют 16 цифр (0 - 9, A (~ 10) - F(~ 15)) и, следовательно, основание 16, поэтому 0x20 = 0 * 16 ^ 0 + 2 * 16 ^ 1.

Двоичные числа имеют 2 цифры и основание 2, поэтому 100b = 1 * 2 ^ 2 + 0 * 2 ^ 1 + 0 * 2 ^ 0.

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

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