для чего используются биты и побитовые операции?

Может кто-нибудь объяснить очень простыми словами, зачем нам нужны побитовые операторы? Я только месяц назад начал программировать.

Я так понимаю, что все хранится в бинарном виде. Я понимаю, что компьютеры считают по основанию 2. И я понимаю побитовые операторы. Я просто не понимаю, какое программирование потребует использования битов и побитовых операторов?

Я попытался найти ответ в Интернете, прочитал что-то про бинарные флаги и инвалидность и еще больше запутался.

Думаю, мне просто интересно, какое приложение в реальной жизни потребует битов и побитовых операторов?


person jason adams    schedule 24.03.2014    source источник
comment
Инвалиды? Что ты имеешь в виду?   -  person harold    schedule 24.03.2014
comment
Итак, вы хотите создать переменную, которая только сообщает вам, является ли что-то истинным или ложным? Ну, вы можете сделать это простым способом: var/on = 1 Проблема возникает, когда вы хотите работать с чем-то вроде инвалидности. Существует много видов инвалидности, и иметь одну переменную для каждой инвалидности дорого с точки зрения используемой памяти, а также утомительно работать с ней. Чтобы решить такую ​​проблему, мы будем использовать бинарные флаги. -- baystation12.net/wiki/index.php/Binary_flags   -  person jason adams    schedule 25.03.2014


Ответы (3)


Вы можете упаковать данные в очень сжатом формате.

Наименьшая сумма, которую может адресовать компьютер x86, составляет байт, то есть 8 бит.

Если ваше приложение имеет 24 флага да/нет (bool), вы бы сохранили их по 1 байту каждый? Это 24 байта данных. Если вы используете биты, то каждый байт содержит 8 этих логических значений, поэтому вам нужно всего 3 байта для 24 значений да/нет:

> 1 Byte per flag:
> 0000 0000 = off
> 0000 0001 = on
> Easy to check: if(b == 0) { /* flag is off */ } else if(b == 1) { /* flag is on */ }

> 1 Bit per flag
> 0011 1101 = Flags 1, 4, 8, 16 and 32 are on, flags 2, 64 and 128 are off
> Packs 8 flags in 1 byte
> Harder to check:
> if( (b & 32) != 0) { /* Flag 32 is on */ }

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

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

Это используется не только для логических значений. Например, некоторые приложения могут захотеть хранить два числа, а не от 0 до 15 — например, Commodore 64, которому действительно нужно было экономить оперативную память везде, где это возможно. Один байт может содержать два таких числа:

> Instead of interpreting this as 8 bits (ranging from 1 to 128)
> this is really two 4 bit numbers:
> 1001 0110
> First Number: 1001 = 1 + 8 = 9
> Second Number: 0110 = 2 + 4 = 6
>
> Getting the first number requires a bit shift to move them into position:
> (b >> 4) turns the above number into this:
> 0000 1001 - this can now be simply cast as a byte and returns 9
>
> The second number requires us to "turn off" the first 4 bits
> We use the AND operator for this: b = (b & 15)
> 15 in decimal is 0000 1111 in binary.
>
> 1001 0110 AND
> 0000 1111 =
> 0000 0110
>
> Once again, the result can be interpreted as a byte and results in the number 6

Еще один действительно изящный трюк — быстро проверить, является ли число четным или нечетным. Нечетное число всегда имеет младший значащий бит (1 бит), а четное число всегда ясно.

Итак, ваша проверка на наличие IsEven выглядит так:

return (b & 1) == 0; // Bit 1 not set - number is even

(Примечание: в зависимости от языка компиляторы МОГУТ решить оптимизировать материал, но в двух словах это все)

person Michael Stum    schedule 24.03.2014
comment
Можете ли вы объяснить, почему первое число: 1001 делится как 1 + 8? это потому что 0b1+0b1000? и зачем нам делить 8 бит на 4 битные числа? это для экономии памяти? - person jason adams; 24.03.2014
comment
@ user3436782 First Number — это пример того, как я разделил 8-битный байт (который обычно имеет 128-64-32-16-8-4-2-1 бит) на 2 4-битные части (обе 8-4-2). -1 8-4-2-1) - это не то, что может сделать компьютер, поэтому сдвиг битов необходим для того, чтобы компьютер его интерпретировал. И да, причина в экономии места. Одним из примеров является сетевой протокол DNS, который подразделяет 1 байт на 4-битное число и 4 логических флага. Это не принято делать, но если вам нужно упаковать как можно больше данных в как можно меньше места, эти приемы появляются. - person Michael Stum; 24.03.2014
comment
Спасибо, Майкл. Думаю, я лучше понимаю, для чего они используются. Может быть, я получу более четкое представление, когда начну изучать больше концепций. - person jason adams; 24.03.2014

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

Я использовал его в реальных бизнес-решениях для хранения состояния, которое лучше всего представлено в виде множества связанных флагов. Как и владение разными видами магии :)

Skills:
    None (0)
    Conjuration (1)
    Evocation (2)
    Illusion (4)
    Necromancy (8)
    Alteration (16)

Теперь я могу хранить то, на что способны волшебники, в одном поле. Если сумма навыков волшебника равна 13, мы знаем, что он знает: Колдовство, Иллюзию и Некромантию. Ко всему этому легко получить доступ с помощью побитовых операций. Используя то, что мы знаем о битах и ​​базе 2, мы можем использовать каждый бит в числе в качестве логического флага, обычно для хранения некоторого связанного состояния (например, опций или магического мастерства, в C# FlagsAttribute очень полезен.

person Zache    schedule 24.03.2014

ну... есть несколько случаев, когда вы можете использовать побитовые операторы. Вот один. Системный вызов linux принимает в качестве аргументов имя пути к файлу и битовую маску, указывающую режим доступа к файлу. Примеры: open("somefile", O_RDWR | O_CREAT | O_TRUNC | S_IWUSR), open("somefile", O_RDONLY). Побитовая операция or позволяет указать много информации в одном аргументе и, следовательно, упрощает интерфейс с ядром.

person Wcrousse    schedule 24.03.2014