Quais são alguns casos de uso do mundo real dos seguintes operadores bit a bit?
- E
- XOR
- NÃO
- OU
- Deslocamento Esquerda / Direita
language-agnostic
bitwise-operators
Louis Go
fonte
fonte
Respostas:
Campos de bits (sinalizadores)
Eles são a maneira mais eficiente de representar algo cujo estado é definido por várias propriedades "sim ou não". ACLs são um bom exemplo; se você tiver quatro permissões discretas (leitura, gravação, execução, alteração de política), é melhor armazená-lo em 1 byte em vez de desperdiçar 4. Elas podem ser mapeadas para tipos de enumeração em vários idiomas para maior comodidade.
Comunicação através de portas / soquetes
Sempre envolve somas de verificação, paridade, bits de parada, algoritmos de controle de fluxo e assim por diante, que geralmente dependem dos valores lógicos de bytes individuais em oposição aos valores numéricos, pois o meio pode ser capaz de transmitir apenas um bit em um tempo.
Compactação, criptografia
Ambos dependem fortemente de algoritmos bit a bit. Veja o algoritmo deflate como exemplo - tudo está em bits, não em bytes.
Máquinas de estado finito
Estou falando principalmente do tipo incorporado em alguma peça de hardware, embora elas também possam ser encontradas em software. Estes são combinatória na natureza - eles podem ser literalmente ficando "compilado" para baixo para um monte de portas lógicas, então eles têm que ser expressa como
AND
,OR
,NOT
, etc.Gráficos Não há espaço suficiente aqui para entrar em todas as áreas em que esses operadores são usados na programação gráfica.
XOR
(ou^
) é particularmente interessante aqui, porque aplicar a mesma entrada uma segunda vez desfará a primeira. As GUIs mais antigas costumavam contar com isso para destacar a seleção e outras sobreposições, a fim de eliminar a necessidade de redesenhos dispendiosos. Eles ainda são úteis em protocolos gráficos lentos (ou seja, área de trabalho remota).Esses foram apenas os primeiros exemplos que inventei - essa dificilmente é uma lista exaustiva.
fonte
Isso é estranho?
É divisível por dois (par)?
fonte
Aqui estão alguns idiomas comuns que lidam com sinalizadores armazenados como bits individuais.
Defina o sinalizador de cobrança:
Limpar sinalizador CallerIDMissing:
Teste se CallerIDMissing e Chargeable estão definidos:
fonte
Eu usei operações bit a bit na implementação de um modelo de segurança para um CMS. Ele tinha páginas que poderiam ser acessadas pelos usuários se eles estivessem em grupos apropriados. Como um usuário pode estar em vários grupos, é necessário verificar se há uma interseção entre os grupos de usuários e os grupos de páginas. Portanto, atribuímos a cada grupo um identificador de potência 2 exclusivo, por exemplo:
OR esses valores juntos e armazenamos o valor (como um único int) com a página. Por exemplo, se uma página puder ser acessada pelos grupos A e B, armazenamos o valor 3 (que em binário é 00000011) como controle de acesso às páginas. Da mesma maneira, armazenamos um valor de identificadores de grupo ORed com um usuário para representar em quais grupos eles estão.
Portanto, para verificar se um determinado usuário pode acessar uma determinada página, basta AND AND os valores juntos e verificar se o valor é diferente de zero. Isso é muito rápido, pois essa verificação é implementada em uma única instrução, sem loop, sem ida e volta ao banco de dados.
fonte
A programação de baixo nível é um bom exemplo. Você pode, por exemplo, precisar escrever um bit específico em um registro mapeado na memória para fazer com que algum hardware faça o que você deseja:
Além disso,
htonl()
ehtons()
são implementados usando os operadores&
e|
(em máquinas cuja endianness (ordem de bytes) não corresponde à ordem da rede):fonte
htons()
ehtonl()
são funções POSIX para trocar umshort
ou umlong
doh
endianness host ( ) para an
ordem de bytes da rede ( ).htonl()
para umint
valor de 32 bits ?long
significa 64 bits em vários idiomas.Eu os uso para obter valores RGB (A) de valores de cores compactados, por exemplo.
fonte
(a & b) >> c
é mais de 5 vezes mais rápido quea % d / e
(nas duas formas de extrair um único valor de cor de um int representando o ARGB). Respectivamente, 6,7s e 35,2s para 1 bilhão de iterações.%
não é o operador Modulus, é o operador Restante. Eles são equivalentes aos valores positivos, mas diferem dos negativos. Se você fornecer as restrições apropriadas (passando um emuint
vez de,int
por exemplo), os dois exemplos deverão ter a mesma velocidade.Quando tenho um monte de sinalizadores booleanos, gosto de armazená-los todos em um int.
Eu os pego usando AND bit a bit. Por exemplo:
etc.
fonte
if (flags.feature_one_is_one) { // turn on feature }
. Está no padrão ANSI C, portanto a portabilidade não deve ser um problema.& = AND:
mascarar bits específicos.
Você está definindo os bits específicos que devem ser exibidos ou não. 0x0 e x limparão todos os bits em um byte, enquanto 0xFF não mudará x. 0x0F exibirá os bits na mordidela inferior.
Conversão:
para converter variáveis mais curtas em variáveis mais longas com identidade de bits, é necessário ajustar os bits porque -1 em um int é 0xFFFFFFFF enquanto -1 em um comprimento é 0xFFFFFFFFFFFFFFFF. Para preservar a identidade, você aplica uma máscara após a conversão.
| = OR
Defina bits. Os bits serão definidos independentemente se já estiverem definidos. Muitas estruturas de dados (campos de bits) possuem sinalizadores como IS_HSET = 0, IS_VSET = 1, que podem ser configurados independentemente. Para definir os sinalizadores, aplique IS_HSET | IS_VSET (em C e montagem, é muito conveniente ler isso)
^ = XOR
Encontre bits iguais ou diferentes.
~ = NÃO
Virar bits.
Pode-se mostrar que todas as operações de bits locais possíveis podem ser implementadas por essas operações. Portanto, se você quiser, pode implementar uma instrução ADD apenas por operações de bits.
Alguns hacks maravilhosos:
http://www.ugcs.caltech.edu/~wnoise/base2.html
http://www.jjj.de/bitwizardry/bitwizardrypage.html
fonte
= ~
, não|=
, que é OU.& = AND
- Por que eu gostaria de limpar todos os bits, por que gostaria de obter uma versão não modificada do byte e o que devo fazer com a menor mordida?xor
por si só. Eu posso pensar em algumas razões pelas quais você pode extrair a menor mordidela. Especialmente se esse petisco inferior fizer parte de uma estrutura de dados e você desejar usá-lo como uma máscara ouOR
com outra estrutura.Criptografia são todas as operações bit a bit.
fonte
Você pode usá-los como uma maneira rápida e suja de hash de dados.
fonte
Eu apenas usei bitwise-XOR (
^
) cerca de três minutos atrás para calcular uma soma de verificação para comunicação serial com um PLC ...fonte
Bitwise & é usado para mascarar / extrair uma certa parte de um byte.
Variável de 1 byte
Especialmente o operador de turno (<< >>) é frequentemente usado para cálculos.
fonte
Este é um exemplo para ler cores de uma imagem de bitmap no formato de bytes
Espero que este pequeno exemplo ajude ....
fonte
No mundo abstrato da linguagem moderna de hoje, não muitos. O arquivo IO é fácil de lembrar, embora esteja exercendo operações bit a bit em algo já implementado e não esteja implementando algo que usa operações bit a bit. Ainda assim, como um exemplo fácil, esse código demonstra a remoção do atributo somente leitura em um arquivo (para que possa ser usado com um novo FileStream especificando FileMode.Create) em c #:
Quanto às implementações personalizadas, aqui está um exemplo recente: criei um "centro de mensagens" para enviar mensagens seguras de uma instalação de nosso aplicativo distribuído para outra. Basicamente, é análogo ao e-mail, completo com Caixa de entrada, Caixa de saída, Enviado etc., mas também possui entrega garantida com recibos de leitura, para que haja subpastas adicionais além de "caixa de entrada" e "enviado". O que isso representou foi um requisito para eu definir genericamente o que está "na caixa de entrada" ou o que está "na pasta enviada". Na pasta enviada, preciso saber o que é lido e o que não é lido. Do que não foi lido, preciso saber o que é recebido e o que não é recebido. Eu uso essas informações para criar uma cláusula where dinâmica que filtra uma fonte de dados local e exibe as informações apropriadas.
Veja como o enum é montado:
Você vê o que isso faz? Anding (&) com o valor de enumeração "Inbox", InboundMemos, eu sei que InboundMemosForMyOrders está na caixa de entrada.
Aqui está uma versão resumida do método que cria e retorna o filtro que define uma exibição para a pasta selecionada no momento:
Extremamente simples, mas uma implementação elegante em um nível de abstração que normalmente não requer operações bit a bit.
fonte
A codificação Base64 é um exemplo. A codificação Base64 é usada para representar dados binários como caracteres imprimíveis para enviar por sistemas de email (e outros fins). A codificação Base64 converte uma série de bytes de 8 bits em índices de pesquisa de caracteres de 6 bits. As operações de bits, deslocamento e andamento, ou não, são muito úteis para implementar as operações de bits necessárias para a codificação e decodificação Base64.
É claro que isso é apenas um dos inúmeros exemplos.
fonte
Estou surpreso que ninguém tenha escolhido a resposta óbvia para a era da Internet. Cálculo de endereços de rede válidos para uma sub-rede.
http://www.topwebhosts.org/tools/netmask.php
fonte
Normalmente, as operações bit a bit são mais rápidas do que multiplicar / dividir. Portanto, se você precisar multiplicar uma variável x por 9, faça o
x<<3 + x
que seriam alguns ciclos mais rápidos quex*9
. Se esse código estiver dentro de um ISR, você economizará tempo de resposta.Da mesma forma, se você deseja usar uma matriz como uma fila circular, seria mais rápido (e mais elegante) lidar com cheques de contorno com operações pouco inteligentes. (o tamanho do seu array deve ter uma potência de 2). Por exemplo:, você pode usar em
tail = ((tail & MASK) + 1)
vez detail = ((tail +1) < size) ? tail+1 : 0
, se desejar inserir / excluir.Além disso, se você desejar que um sinalizador de erro mantenha vários códigos de erro juntos, cada bit poderá conter um valor separado. Você pode AND com cada código de erro individual como uma verificação. Isso é usado nos códigos de erro do Unix.
Além disso, um bitmap de n bits pode ser uma estrutura de dados muito legal e compacta. Se você deseja alocar um pool de recursos do tamanho n, podemos usar n-bits para representar o status atual.
fonte
Parece que ninguém mencionou matemática de ponto fixo.
(Sim, eu sou velho, ok?)
fonte
Um número é
x
uma potência de 2? (Útil, por exemplo, em algoritmos em que um contador é incrementado e uma ação deve ser executada apenas o número logarítmico de vezes)Qual é o bit mais alto de um número inteiro
x
? (Isso, por exemplo, pode ser usado para encontrar a potência mínima de 2 que é maior quex
)Qual é o
1
bit mais baixo de um número inteirox
? (Ajuda a encontrar o número de vezes divisível por 2.)fonte
x & -x
.Operadores bit a bit são úteis para loop de matrizes cujo tamanho é a potência 2. Como muitas pessoas mencionaram, os operadores bit a bit são extremamente úteis e são usados em sinalizadores , gráficos , redes , criptografia . Não só isso, mas eles são extremamente rápidos. Meu uso favorito pessoal é fazer um loop de uma matriz sem condicionais . Suponha que você tenha uma matriz baseada em índice zero (por exemplo, o índice do primeiro elemento é 0) e precise fazer um loop indefinidamente. Por indefinidamente, quero dizer passar do primeiro elemento ao último e retornar ao primeiro. Uma maneira de implementar isso é:
Esta é a abordagem mais simples, se você deseja evitar a instrução if , pode usar a abordagem de módulo da seguinte forma:
A desvantagem desses dois métodos é que o operador do módulo é caro, pois procura um restante após a divisão inteira. E o primeiro método executa uma instrução if em cada iteração. Com o operador bit a bit, no entanto, se o comprimento da sua matriz for uma potência de 2, você poderá gerar facilmente uma sequência como
0 .. length - 1
usando o&
operador (bit a bit e) dessa formai & length
. Então, sabendo disso, o código de cima se tornaAqui está como isso funciona. No formato binário , todo número que é o poder de 2 subtraído por 1 é expresso apenas com um. Por exemplo 3 em binário é
11
, 7 é111
, 15 é1111
e assim por diante, você entendeu. Agora, o que acontece se você tiver&
algum número em relação a um número composto apenas por números binários? Digamos que fazemos isso:Se
num
for menor ou igual a 7, o resultado seránum
porque cada bit&
com 1 é o próprio. Senum
for maior que 7, durante a&
operação, o computador considerará os zeros à esquerda do 7, que, obviamente, permanecerão como zeros após a&
operação, apenas a parte à direita permanecerá. Como no caso de9 & 7
em binário, pareceráo resultado será 0001, que é 1 em decimal e aborda o segundo elemento na matriz.
fonte
Eu os uso para opções de seleção múltipla, dessa forma, armazeno apenas um valor em vez de 10 ou mais
fonte
também pode ser útil em um modelo relacional sql, digamos que você tenha as seguintes tabelas: BlogEntry, BlogCategory
tradicionalmente, você poderia criar um relacionamento nn entre eles usando uma tabela BlogEntryCategory ou, quando não houver muitos registros BlogCategory, você poderia usar um valor no BlogEntry para vincular a vários registros BlogCategory, como faria com enumerações sinalizadas, na maioria dos RDBMS também existem operadores muito rápidos para selecionar nessa coluna 'sinalizada' ...
fonte
Quando você deseja alterar apenas alguns bits das saídas de um microcontrolador, mas o registro no qual gravar é um byte, você faz algo assim (pseudocódigo):
Obviamente, muitos microcontroladores permitem alterar cada bit individualmente ...
fonte
Se você quiser calcular seu número mod (%) uma certa potência de 2, poderá usar
yourNumber & 2^N-1
, que neste caso é o mesmo queyourNumber % 2^N
.Isso provavelmente é útil apenas como uma alternativa à operação de módulo com um dividendo muito grande que é 2 ^ N ... Mas mesmo assim, seu aumento de velocidade sobre a operação de módulo é desprezível no meu teste no .NET 2.0. Suspeito que os compiladores modernos já executem otimizações como esta. Alguém sabe mais sobre isto?
fonte
%
a operação Remainder, eles tratam os negativos de maneira diferente. No entanto, se você passaruint
para%
, o compilador C # realmente produzirá código de máquina usando AND bit a bit quando o segundo argumento for uma potência pré-conhecida de dois.Eu os vi usados em sistemas de controle de acesso baseados em funções.
fonte
Existe um uso no mundo real na minha pergunta aqui -
Responder apenas à primeira notificação WM_KEYDOWN?
Ao consumir uma mensagem WM_KEYDOWN nas janelas C api bit 30 especifica o estado da chave anterior. O valor é 1 se a chave estiver pressionada antes do envio da mensagem ou será zero se a chave estiver ativada
fonte
Eles são usados principalmente para operações bit a bit (surpresa). Aqui estão alguns exemplos do mundo real encontrados na base de código PHP.
Codificação de caracteres:
Estruturas de dados:
Drivers de banco de dados:
Implementação do compilador:
fonte
Sempre que iniciei a programação C, entendi as tabelas verdadeiras e tudo mais, mas nem tudo funcionou até o momento em que li este artigo http://www.gamedev.net/reference/articles/article1563.asp (que dá exemplos da vida real)
fonte
x == 1
ey == 2
, entãox || y
avalia como 1 ex | y
avalia como 0. Nem vejo por quex^true
é superior a isso!x
. É mais digitado, menos idiomático e, sex
não for um,bool
não é confiável.x^true
é superior à!x
ésome->complicated().member->lookup ^= true;
Não existem versões composto de atribuição de operadores unários.Eu não acho que isso conta como bit a bit, mas o Ruby Array define operações de conjunto por meio dos operadores inteiros normais em bits. Então
[1,2,4] & [1,2,3] # => [1,2]
. Da mesma forma paraa ^ b #=> set difference
ea | b #=> union
.fonte
A solução linear da Tower Of Hanoi usa operações bit a bit para resolver o problema.
A explicação para esta solução pode ser encontrada aqui
fonte