Воспроизведение кода сдвига битов с C ++ на C #

Я пытаюсь преобразовать перечисление из кода C ++ в код C #, и у меня возникают проблемы, когда я оборачиваюсь вокруг него. Код C ++:

enum FOO {
FOO_1 = 0,
FOO_2,
// etc
}

#define MASK(x)  ((1 << 16) | (x))

enum DISP
{
DISP_1 = MASK(FOO_1),
DISP_2 = MASK(FOO_2),
// etc
}

Что я не понимаю, так это то, что делает MASK, и как я могу либо эмулировать функциональность в C #, либо понять, что он делает, и установить enum DISP вручную без него.

Я не уверен, что то, что я говорю, имеет смысл, но этого следует ожидать, когда я не совсем уверен, на что я смотрю.

6

Решение

MASK(x) строит число по ORв ряд x с двоичным числом 10000000000000000 (один сдвинут влево 16 раз).

В C # вы можете использовать выражение напрямую, например так:

enum FOO {
FOO_1 = 0,
FOO_2,
// etc
}

enum DISP
{
DISP_1 = (1<<16) | (int)(FOO.FOO_1),
DISP_2 = (1<<16) | (int)(FOO.FOO_2),
// etc
}
6

Другие решения

когда вы сдвигаете бит, он сдвигает все 1 и 0 влево или вправо на некоторое количество значений.

в твоем случае 1 << 16 создает 10000000000000000 в двоичном формате. (да, это 16 нулей).

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

Если, например, вы используете MASK(FOO_4) (который имеет буквальное значение 3) 3 равно 11 в двоичном формате, поэтому результат будет 10000000000000011. Это функционально аналогично добавлению 65 536 к каждому значению.

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

Чтобы сделать то же самое в C # попробуйте это:

enum Foo { //this may not be needed anymore?
FOO_1 = 0, FOO_2, ... etc
}

enum Disp { //DISP_2 gets the next value ie 65536 + 1, and so forth
DISP_1 = 65536, DISP_2, DISP_3, ... etc
7

Просто замени MASK с тем, что это определено как ( << а также | операторы существуют и в C #):

enum DISP
{
DISP_1 = ((1 << 16) | FOO.FOO_1),
DISP_2 = ((1 << 16) | FOO.FOO_2)
}

Если вам интересно, что именно выполняют операторы shift или or, вы принимаете двоичное значение 0000000000000001 и сдвигает его на 16 значений влево: 1000000000000000,

Другой пример, (000001101 << 3) становится 001101000,

Оператор or берет все значения 1 из любого операнда и устанавливает значение результата в 1.

Например, 0001 | 0110 становится 0111,

Итак, возьмите DISP_2:

  (0b00000000000000001 << 16) | 0b00000000000000010)
= (0b10000000000000000 | 0b00000000000000010)
= (0b10000000000000010)
= 65538

(Я знаю 0b формат не работает в C # и не является стандартным в C, но более полезно использовать двоичную нотацию вместо шестнадцатеричной, чтобы легче было видеть, что делают операторы)

2

Числовые значения, которые DISP_x равны:

DISP_1 == 0x10000
DISP_2 == 0x10001
DISP_3 == 0x10002
...
0

Оператор сдвига битов работает в C #, а макрос определения — нет.

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

Конечно, вы знаете, что | является побитовым оператором ИЛИ. И на всякий случай какой оператор << делает сдвиг двоичного файла влево:

1 << 16 = 10000000000000000_2 //those are 16 zeroes and _2 indicates binary

В очереди:

10000000000000000_2 = 65536

Это является эквивалентом умножения числа на 2 количество раз, указанное вторым операндом.

1 << 1 = 2
1 << 2 = 4
1 << 3 = 8

Это верно, это умножение числа на степень двух:

1 << 1 <=> 1 * 2^1 = 2
1 << 2 <=> 1 * 2^2 = 4
1 << 3 <=> 1 * 2^3 = 8

Сейчас, с FOO_1 = 0 затем

DISP_1 = MASK(FOO_1)
=>
DISP_1 = ((1 << 16) | (FOO_1))
=>
DISP_1 = (65536 | (FOO_1))
=>
DISP_1 = (65536 | FOO_1)
=>
DISP_1 = (65536 | 0)
=>
DISP_1 = 65536

Делать то же самое для FOO_2 который я беру, имеет значение 1, которое даст вам:

DISP_2 = (65536 | FOO_2)
=>
DISP_2 = (65536 | 1)
=>
DISP_2 = 65537

При этом правильно работает следующее:

enum FOO
{
FOO_1 = 0,
FOO_2,
// etc
}

enum DISP
{
DISP_1 = (1<<16) | (int)(FOO.FOO_1),
DISP_2 = (1<<16) | (int)(FOO.FOO_2),
// etc
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector