Sunday 22 April 2018

Opções de máscara binária


Usando Bit Flags e EnumSets em Java.
Os sinalizadores de bits, comumente referidos como campos Bit, são uma forma eficiente de armazenar vários valores booleanos relacionados em um único tipo primitivo. Internamente representado em binário, você pode decidir quanto grande o tipo de armazenamento precisa ser - por exemplo, um inteiro de Java fornecerá espaço para 31 bandeiras. Sendo um tipo de 32 bits, você assumiria ter acesso a essas bandeiras, no entanto, devido ao fato de ser um valor assinado, o bit mais significativo é reservado para armazenar seu sinal +/-.
As bandeiras normalmente são armazenadas como constantes públicas dentro da classe relacionada, por exemplo, a classe Padrão inclui os sinalizadores 'CASE_INSENSITIVE' e 'MULTILINE' para alterar os critérios de correspondência. Definir os valores como potências incrementais de 2 permite ao usuário compor várias constantes juntas usando o | (OR) para obter a combinação de bandeira desejada. O implementador é então capaz de basear a execução dos métodos nos sinalizadores passados, verificando a presença do valor constante usando o & amp; (AND) como uma máscara de bits. Essa idéia pode ser descrita de forma mais significativa usando o exemplo abaixo.
Como você pode ver, eu definei 5 constantes diferentes com valores específicos que correspondem a diferentes representações binárias. Em relação à constante final que eu configurei para o decimal 15, em essência, isso enche todas as combinações de valores criadas anteriormente. Dentro do bloco de método, verifico a presença de cada sinalizador, mascando o parâmetro 'flags' com o valor constante. Se o valor resultante for igual à constante especificada, podemos atuar nesta condição.
Acima estão alguns exemplos do método que está sendo usado de múltiplas maneiras. O terceiro exemplo mostra a capacidade de compor valores de várias bandeiras (representação binária 1100).
O uso tradicional de bit flags ocorreu por muitos anos e é um mecanismo de armazenamento muito performant (especialmente na renderização gráfica). No entanto, pode ser muito fácil para o código resultante ser difícil de entender. Outra questão flagrante é que eles não são de tipo seguro, anulando os benefícios de ter um sistema de tipo implementado. No entanto, EnumSets tem a eficiência de bit flags, mas sem a perda de segurança, o sistema de tipo fornece. Devo salientar que existe outra implementação do Set chamada BitSet, que fornece funcionalidades semelhantes. Recomenda-se que, se você deseja um sistema de sinalização, como o caso de uso descrito, um EnumSet fornecerá os melhores resultados.
No caso de um EnumSet, você deve primeiro definir seu tipo enumerado, que encapsula todas as constantes desejadas. Sempre que eu defini a constante 'ALL_OPTS' no primeiro exemplo, criei um EnumSet consistindo de todas as constantes no tipo de bandeira. EnumSet implementa a interface Set, para que você possa usá-lo como faria com um conjunto típico, chamando 'contains' no mesmo para consultar a presença de um determinado sinalizador.
Acima estão alguns exemplos de utilização do EnumSet no lugar de um típico sistema de sinalização de bits. Como você pode ver, podemos completar todos os exemplos que foram possíveis no caso de uso anterior, mas desta vez é mais legível e somos menos propensos a erros.

toco.
Apenas outro blog do WordPress.
Pós-navegação.
Um Quick Bitmask HOWTO para programadores.
Atenção: o material Highly Geeky segue.
Atualmente, estou trabalhando em um grande banco de dados para um cliente. Atualmente, eu realmente estou fazendo uma nova versão do banco de dados em uma máquina de gritar normalizada. Eu encontrei um problema recentemente em que alguns dos valores são armazenados como bitmasks. Eu sabia o que era uma máscara de bits, mas geralmente os considerava como magia vudu deixada para hackers loucos de C. Até agora. Eu entrei em contato com meu mentor do hacker louco do Voodoo, Jeremy Brand, e perguntei como eles trabalhavam.
Aqui é um rápido tutorial:
em vez de contar 0, 1, 2, 3, 4, 5 e # 8230; você poderia com poderes de 2.
Quando você faz uma coisa com um desses poderes de dois, você pode.
adicione-os a outros poderes de 2 e, em seguida, divida o que.
você começou com novamente.
A soma de seus identificadores é 7 (vamos chamar este $ soma).
Então, mais tarde você pode verificar 7 para ver o que está em sua cesta:
$ sum mod 4 igual a 0? (então não há maçã no carrinho)
o $ sum mod 2 equivale a 0? (então não há laranja no carrinho)
o $ sum mod 1 email 0? (então não há banana no carrinho)
Usar bitmasmas não é mais fácil de usar, mas é rápido.
É rápido porque os computadores já são em bits. Este exemplo.
está usando memória de 3 bits. Normalmente, você terá 16 opções (como eu.
tem 3 aqui) por causa do tamanho de um número inteiro. Se você é sortudo.
você estará usando C ou mesmo o mysql que pode acessar todos os 32 bits de um.
inteiro, você terá 32 opções.
A razão pela qual os computadores usam base-2 para começar são porque.
Com o hardware de armazenamento, há realmente apenas dois estados: ligado e desligado.
As unidades mais simples que você pode armazenar e desligar mais.
armazenamento que o dispositivo pode ter.
FYI, você pode usar o google para sua calculadora:
Finalmente, isso faz sentido. Ainda estou completamente perdido na matemática real que faz isso funcionar (o que me irrita), mas consegui obter um programa de prova de conceito funcionando, o que pode ajudar outros programadores deficientes em bitmask lá fora:
O truque é o & amp ;. Se o resultado for 0 (zero), o valor da máscara de bits única não está presente na soma da máscara de bits. Tenho certeza de que isso tem algo com o fato de que você não pode adicionar nenhuma lista separada de valores de máscara de bits e obter a mesma soma duas vezes (ou seja, 1 + 2 + 4 = 7, 2 + 4 + 8 = 14). Mais uma vez, eu só sei # 8220; funciona [tm] & ​​# 8221 ;. Espero que isso ajude alguém a lá.
Eu principalmente escondiendo isso aqui, então a próxima vez que minha mente retardada pode se enrolar em torno de máscaras de bits, eu posso verificar novamente em meu próprio site. Se você tiver dúvidas sobre este não envie um e-mail para mim, porque eu ainda acho que pequenos homens verdes fazem esse truque matemático & # 8220; # 8221; trabalhos. Porra, eu gostaria de obter um diploma de Ciência da Computação em vez de uma Informação de Computador. Sys. grau.
16 pensamentos sobre & ldquo; Um Quick Bitmask HOWTO para Programmers & rdquo;
Finalmente! Eu vi isso muitas vezes, mas não consegui descobrir o nome, obrigado.
Você ajudou pelo menos um codificador deficiente em bitmask 🙂
Eu não posso acreditar nos tipos de pessoas que se chamam programadores nos dias de hoje. E os gerentes não conhecem; para eles, qualquer um que possa jogar algumas palavras-chave arrumadas deve saber o que eles estão fazendo. E, portanto, a quantidade irresistível de sistemas de software de amaldiçoamento, de qualidade inferior, com documentação fraca e design ainda pior. Você senhor, é um idiota, e eu odeio seu tipo.
Você não tem IDEA que tipo de programador eu sou. Antes de tirar a boca, você provavelmente deveria tomar o tempo para me conhecer. Só porque eu não sabia o que era uma máscara de bits (ou como usá-la efetivamente) não significa que eu não sou bom com SQL, OOP, etc. Pelo menos eu entendi isso para mim mesmo Saiba como usá-los e pode reconhecer o fato de que eles são uma solução mais elegante para muitos problemas.
Que tal você derrubar alguém para tentar aprender a ser um programador melhor? Você, senhor, é um idiota, e eu odeio você.
Eu acho que a idéia de bitmasks é algo que nem todos devem saber. Você pode desenvolver aplicativos por anos e nunca tropeçar com a necessidade deles, especialmente quando não usa DBs.
As máscaras de bits são úteis, mas onde eu começo a ficar nervoso são as mudanças de bits, p. em Java. Eles são ainda mais estranhos (e acho que o código tende a ficar muito ilegível).
Aren't Integer comparações sempre transformadas em bitmasks por um compilador decente?
Então, ao invés de dissing alguém, como eu só me ajudarei 😉 A matemática que você está procurando atrás de tudo isso é extremamente simples. O problema é que, para alguns, eles não falam binário. Suponhamos que nós temos quatro bits. Não bytes, bits. Então, alinhe, e eles se parecem com isto:
Olhando para esse padrão, você notará que o 1 está movendo um espaço para a esquerda (daí a mudança de bit) para cada novo valor.
Ok, agora vamos falar sobre & # 8220; e # 8221; Bitwise & # 8220; e & # 8221 ;. O que isso significa? Bem, se você comparar dois * binários * números como:
0010 = 4 decimais.
0011 = 5 decimais.
Veja o número mais à direita de cada conjunto de bits. O topo é 0 e o inferior é 1. Existem apenas duas regras para lembrar:
Lembre-se desta matemática binária (base 2), não matemática decimal (base-10), e não usamos & # 8220; bitwise e (& # 038;) & # 8221; em matemática decimal, apenas operadores gostam de (+, -, /, x,% entre outros).
Então, & # 8220; e & # 8221; Cada coluna de bits e você obtém o resultado:
0011 = 5 decimais.
0010 = 4 decimais.
0010 = 4 decimais = Resultado.
Que bem isso faz? Bem, assim como sua cafeteira, você acabou de criar um filtro. Imagine se isso parece ser assim:
0011 = 5 decimais = A user & # 8217; s & # 8220; direitos de acesso & # 8221 ;.
0010 = 4 decimal = A permissão necessária para acessar esta página.
Pergunta de US $ 60 000: se o usuário chegar nesta página, eles vêem a página?
Mas sim!! O segundo bit está definido em seus & # 8220; direitos de acesso & # 8221 ;.
Espero que ajude.
Btw. Trabalhei há muito tempo em software, incluindo alguns projetos renomados mundiais (NFS: Underground, por exemplo). Aprendi, se alguém tiver atitude, ele acompanha a insegurança. O melhor e o mais brilhante é fácil, acessível e sempre pronto para aprender. Ninguém sabe tudo sobre tudo.
Ainda assim, tenho duas sugestões:
a) Você deve bitwise OR (|) os valores para compor a máscara de bits, em vez de adicionar (apenas por motivos históricos;));
b) Para testar, você deve bit a bit AND a máscara de bits com um valor e, em seguida, comparar com o mesmo valor testado (em vez de 0);
Suponha que você tenha a seguinte bitmask:
1010 & # 8211;> bitmask (10 em decimal)
E você quer testar para:
0110 & # 8211;> valor (6 em ​​decimal)
Se você tiver bit a bit AND (& # 038;) os dois, você obterá:
0010 & # 8211;> bitmask & # 038; valor (2 em decimal)
O que é maior do que zero, provocando TRUE. No entanto, o valor do teste não está dentro da máscara de bits.
Então, seu script funciona se os valores que estão sendo testados são potências de 2, mas falham de outra forma.
Você poderia facilmente torná-lo à prova de prova ao testar o mesmo valor, assim:
função testbitmask ($ value, $ bitmask)
se (($ value & # 038; $ bitmask) == $ value) retornar TRUE;
Esta função funciona se a sua bitmascara é composta por poderes de 2 ou qualquer outra combinação de números.
Note-se que existe uma razão para que bitmasks sejam feitas de poderes de dois. No exemplo dado, a máscara de bits 1010 deve representar os valores 2 (0010) e 8 (1000), OR.
Se você adicionar 10 (que é 1010 em binário) para a máscara de bits, você obteria # 8230; 1010! Como, então, você poderia saber se a máscara de bits contém 2, 8 ou 10? Bem, você não conseguiu.
Para evitar esse problema, você só deveria usar os poderes de dois na sua máscara de bits, pois esses números deslocam um bit para o lado esquerdo, assim:
Mas, como em algumas situações, é útil usar outros números (você pode, se você tiver cuidado), seus scripts melhor estarão prontos ... 🙂
Espero que isto ajude!
Quanto a & # 8220; Mr. & # 8221; O comentário de John, acho que ele deve ter nascido ensinado ou algo assim # 8230; 😛
então eu ainda tenho dúvidas sobre este & # 8230;
91 | 92 = 95 (1011011 | 1011100 = 1011111)
95 & # 038; 91 = 91 CORRETA.
95 & # 038; 92 = 92.
Eu reconheço que os poderes de 2 devem ser usados ​​para evitar apenas essa complicação. No entanto, eu tenho um gerenciador de desenvolvimento que está convencido de que pode ser feito com qualquer conjunto de números. Alguém poderia iluminar para mim como eu posso usar não poderes de 2 em uma máscara de bits e ainda ser capaz de evitar falsos positivos?
então eu ainda tenho dúvidas sobre este & # 8230;
91 | 92 = 95 (1011011 | 1011100 = 1011111)
95 & # 038; 91 = 91 CORRETA.
95 & # 038; 92 = 92.
Eu reconheço que os poderes de 2 devem ser usados ​​para evitar apenas essa complicação. No entanto, eu tenho um gerenciador de desenvolvimento que está convencido de que pode ser feito com qualquer conjunto de números. Alguém poderia iluminar para mim como eu posso usar não poderes de 2 em uma máscara de bits e ainda ser capaz de evitar falsos positivos?
Você precisa usar bitmasks.
Se você quiser mais opções, use um campo de máscara de bits maior (por exemplo, 0000000 em vez de apenas 0000).
Uma coisa que vou adicionar, o principal problema com estes (e eu não gosto muito) é que você pode ficar sem bit / flags que você pode atribuir rapidamente.
Por exemplo, um número de 32 bits significa que você só pode ter até 32 bandeiras de permissão diferentes, ou itens em seu carrinho etc.
Você não usaria uma máscara de bits para lidar com os itens que um usuário tem em seu carrinho de compras, pois haveria 1000 itens (e para ter 1000s de itens suportados, você precisaria de uma máscara de bits de 1000 bits + para lidar com cada item).
Obrigado. Muito bom tutorial e ótimas respostas! Com exceção do único cara que deve morrer e limpar o pool de genes um pouco & # 8230 ;.
Esse joão deve ser totalmente retardado.
Quão estúpida pode ser uma pessoa?
Obrigado! Fui encarregado de trabalhar com um db que usa máscaras de bits e quase desenhou um espaço em branco. Eu esqueci completamente como tudo se juntou. Este artigo lembrou totalmente o padrão de pensamento de bits para mim!
Eu acho que John tem um ponto, embora ele seja um idiota. Um verdadeiro programador entende os conceitos subjacentes, isso deve ser aprendido quando você inicia a programação pela primeira vez. Ligar a si próprio (no sentido literal, não o autor) um profissional quando você não conhece os princípios básicos é como se chamar de mecânico e não saber que os carros usam motores de combustão, mas que consertam os motores de forma feliz, porque eles usam peças. Eu não gostaria que o mecânico funcionasse no meu carro. Note-se que, na minha analogia artificial, o mecânico não precisa conhecer a termodinâmica, simplesmente como funciona de modo geral, assim como um programador não precisa usar o microcódigo ou o montador.
Eu sou uma estudante junior e nunca mais ouvi falar de bitmask até hoje. Ocorreu no meu trabalho @ IT quando eu perguntei a um dos nossos & # 8220; gênios & # 8221; para um tutorial sobre algo. Assim como foi mencionado em uma publicação anterior, o melhor no campo é o mais útil e humilde. Aprendi que as pessoas inseguras que andavam por aí dizendo aos analfabetos que são hackers e programadores têm a atitude de John e acabam por falhar por causa disso. O trabalho em equipe é o melhor ambiente de aprendizagem na minha opinião. É impossível saber tudo.
Olá, eu coloquei-se sobre isso procurando uma atualização (eu vi isso uma vez antes em uma aula e esta seria minha primeira aplicação).
Posso estar confuso, mas acho que pode haver um problema com seu algoritmo de leigos:
Nosso carrinho pode ter os seguintes itens nele (com os valores fornecidos em seu exemplo.)
Vamos assumir que apenas uma laranja e uma maçã estão no carrinho.
sum mod 4 0 (uma maçã está no carrinho)
sum mod 2 = 0 (uma laranja NÃO está no carrinho) - & gt; ERRO.
Mas e se nós tivéssemos uma maçã no carrinho.
Isso não está funcionando porque estamos lidando com números inteiros no exemplo? (Tive a impressão de que o compilador e a velocidade de troca de bits dentro de um processador cuidariam a conversão).
Se uma máscara de bits pode ser aplicada com números inteiros, eu suspeito que eu preciso aplicar mais do que um mod para obter o resultado. Você pode me dizer o que eu faltava?
PS: Desculpe por escrever isso cerca de 3 anos de atraso; & gt;)

Swift 3.0.
Quase idêntico ao Swift 2.0. OptionSetType foi renomeado para OptionSet e enums são escritas minúsculas por convenção.
Em vez de fornecer uma opção nenhuma, a recomendação Swift 3 é simplesmente usar um literal de matriz vazia:
No Swift 2.0, as extensões de protocolo cuidam da maior parte do gabarito para estas, que agora são importadas como uma estrutura que está em conformidade com OptionSetType. (RawOptionSetType desapareceu a partir do Swift 2 beta 2.) A declaração é muito mais simples:
Agora podemos usar semânticas baseadas em conjunto com MyOptions:
Olhando para as opções Objective-C que foram importadas pela Swift (UIViewAutarização, por exemplo), podemos ver que as opções são declaradas como uma estrutura que está em conformidade com o protocolo RawOptionSetType, que, por sua vez, está em conformidade com _RawOptionSetType, Equatable, RawRepresentable, BitwiseOperationsType e NilLiteralConvertible . Podemos criar o nosso próprio como este:
Agora, podemos tratar este novo conjunto de opções, MyOptions, tal como descrito na documentação da Apple: você pode usar uma sintaxe semelhante ao enum:
E também se comporta como se esperássemos opções para comportar-se:
Últimas: Modificações para Swift 1.1 beta 3.
Xcode 6.1 Beta 2 trouxe algumas alterações ao protocolo RawOptionSetType (veja esta entrada de blog Airspeedvelocity e as notas da versão da Apple).
Com base no exemplo Nate Cooks, aqui está uma solução atualizada. Você pode definir sua própria opção como esta:
Pode então ser usado dessa forma para definir variáveis:
E assim teste para bits:
Exemplo Swift 2.0 da documentação:
Você pode encontrá-lo aqui.
Em Swift 2 (atualmente beta como parte do beta Xcode 7), NS_OPTIONS, os tipos de estilo são importados como subtipos do novo tipo OptionSetType. E graças ao novo recurso Extensões de protocolo e à forma como o OptionSetType é implementado na biblioteca padrão, você pode declarar seus próprios tipos que estendem o OptionsSetType e obter todas as mesmas funções e métodos que importaram NS_OPTIONS.
Mas essas funções não são mais baseadas em operadores aritméticos bit-bit. Que trabalhar com um conjunto de opções boleanas não exclusivas em C requer máscaras e bits em um campo é um detalhe de implementação. Na verdade, um conjunto de opções é um conjunto. uma coleção de itens exclusivos. Então, OptionsSetType obtém todos os métodos do protocolo SetAlgebraType, como a criação da sintaxe literal da matriz, consultas como contém, mascaramento com interseção, etc. (Não há mais que lembrar qual personagem engraçado usar para qual teste de associação!)
Se você não precisa interoperar com Objective-C e quiser apenas a semântica de superfície de máscaras de bits em Swift, escrevi uma "biblioteca" simples chamada BitwiseOptions que pode fazer isso com enumerações Swift regulares, por exemplo:
e assim por diante. Nenhum pedaço real está sendo lançado aqui. Estas são operações definidas em valores opacos. Você pode encontrar a essência aqui.
Se a única funcionalidade que estamos precisando é uma maneira de combinar opções com | e verifique se as opções combinadas contêm uma opção específica com & amp; uma alternativa à resposta de Nate Cook poderia ser esta:
Crie um protocolo de opções e sobrecarregue | e & amp; :
Agora podemos criar opções estruturadas de forma mais simples assim:
Eles podem ser usados ​​da seguinte forma:
Como Rickster já mencionou, você pode usar OptionSetType no Swift 2.0. Os tipos NS_OPTIONS são importados como compatíveis com o protocolo OptionSetType, que apresenta uma interface definida para opções:
Isso lhe dá essa maneira de trabalhar:
Apenas publicando um exemplo extra para qualquer outra pessoa que se perguntou se você poderia combinar opções compostas. Você pode, e eles combinam como você esperaria se você estivesse acostumado com bons e antigos campos de bits:
Ele aplana o conjunto [.AB,.X] para [.A,.B,.X] (pelo menos semanticamente):
Ninguém mais mencionou isso - e eu meio que maltratou depois de algum brincadeira - mas um Swift Set parece funcionar bastante bem.
Se pensarmos (talvez para um diagrama de Venn?) Sobre o que um pouco de máscara representa realmente, é um conjunto possivelmente vazio.
Claro, ao abordar o problema dos primeiros princípios, perdemos a conveniência de operadores bit a bit, mas ganhamos poderosos métodos baseados em conjuntos que melhoram a legibilidade.
Aqui está o meu brincadeira, por exemplo:
Eu acho isso agradável porque sinto que ele vem de uma abordagem de princípios básicos para o problema - bem como Swift - ao invés de tentar adaptar as soluções de estilo C.
Também gostaria de ouvir alguns casos de uso de Obj-C que desafiariam esse paradigma diferente, onde os valores brutos inteiros ainda mostram mérito.
A fim de evitar a codificação dura das posições dos bits, o que é inevitável quando se usa (1 & lt; 0), (1 & lt; 1), (1 & lt; & lt; 15) etc. ou pior ainda 1, 2, 16384 etc. ou alguma variação hexadecimal, primeiro se poderia definir os bits em um enum, então deixe o enum fazer o cálculo bit ordinal:
Re: Criações de sandbox e bookmark usando conjuntos de opções com várias opções.
solução para a necessidade de combinar opções para criações, útil quando nem todas as opções são mutuamente exclusivas.
A resposta de Nate é boa, mas eu faria DIY, assim:
Use um Tipo de Conjunto de Opções, no swift 3 use OptionSet.
Eu uso o seguinte Eu preciso dos dois valores que posso obter, rawValue para arrays de indexação e valor para sinalizadores.
E se alguém precisar de mais, apenas adicione uma propriedade calculada.

Usando bitmasks para armazenar configurações.
Muitas vezes, precisamos armazenar vários booleanos para determinar as configurações de um usuário. Bitmasks são uma boa maneira econômica de fazê-lo. A idéia é usar um único número inteiro onde cada bit representa um desses booleanos. Isso é melhor do que salvar cada configuração individual em uma coluna de banco de dados diferente.
Escolha posições de bits para cada configuração. Digamos que queremos armazenar as configurações de notificação.
Agora vamos desativar todas as configurações:
Agora vamos ativar notificações de comentários:
Vamos ver como isso parece em binário:
O bit na posição 1 (COMENTÁRIOS) foi definido como 1 enquanto o resto não mudou.
A operação 1 & lt; & lt; N coloca (desloca) o valor 1 para a posição N de modo que, por exemplo:
Agora | e & amp; são as operadoras OR e AND usuais, mas aplicadas em um nível de bit para que:
Vemos que a | = 1 & lt; & lt; N liga o bit N-posicionado no inteiro a.
inverte todos os bits em uma variável para que:
O que é todos os bits definidos para 1, exceto o bit 1 e o bit 3, se falamos de números inteiros assinados.
Para desligar um pouco, simplesmente faça.
(1 & lt; & lt; COMMENTS) terá todos os bits ON exceto o que está na posição COMENTÁRIOS.
Para verificar se as configurações específicas estão ON, basta verificar.
Escrito por Emmanuel Turlay.
15 Respostas.
Isso é ótimo. Uma queda potencial é que você perde a capacidade de consultar e informar sobre essas configurações. "Mostre-me os usuários com seguidores desativados" torna-se um pouco (ha) mais difícil.
Esse é um ponto justo.
& # x000A; Se eu não estou enganado, todos os sabores do SQL suportam operações bit a bit não? Assim, pode-se consultar com SELECT * FROM usuários WHERE configurações & amp; (1 & lt; 3) & gt; 0.
@ neutralino1, essa é realmente a solução para isso. Eu adoro bitmasks também, eles certamente tornam algumas tarefas muito mais fáceis (e economizam muitas colunas extras em seu banco de dados).
MAS, você sempre tem que ter cuidado ao usá-los, e não apenas jogar tudo lá: P.
Na verdade, o uso de bitmasks requer alguns testes sérios.
& # x000A; e você não pode usá-lo para tudo. No meu caso, eu uso isso para uma coleção estúpida de caixas de seleção.
Esta teria sido a única maneira de coisas armazenadas do dev de volta, quando a memória era um problema. Não seria bom ver o quão rápido o código moderno poderia ser se o tempo fosse gasto para acelerá-lo.
& # x000A; eu realmente aprendi essa técnica enquanto codificava o experimento ATLAS no CERN, que contém milhares de chips eletrônicos, onde o espaço físico e o espaço lógico são recursos limitados.
@ neutralino1 Sim, é definitivamente uma técnica subutilizada. Eu usei uma técnica semelhante em um micro-controlador para um alarme anti-roubo. Com 8 zonas, precisamos de apenas 3 bytes para controlar se estão ativados, alarmados e disparados. Então é apenas uma questão de configurar alarmes / interruptores e LEDs para disparar esses pontos.
& # x000A; as operações Bitwise não são mais ensinadas no fluxo principal.
@mikeymike, acho que você vai apreciar este.
bitmaps em ruby? Voce deve estar brincando.
& # x000A; Se você estiver usando bitmaps na memória, é necessário alocar mais memória para objetos para trabalhar com eles do que economizar espaço. & # x000A; Se você estiver usando bitmaps no banco de dados, você não pode trabalhar com esses dados de forma sensata (sem índices, sem consultas limpas), para que você use bitfield apenas como formato de armazenamento aleijado. Além disso, cada banco de dados possui estruturas próprias, performantes e indexáveis ​​para armazenar esses dados. & # x000A; & # x000A; & # x000A;
Não mencionando que nunca esqueciaria a legibilidade do sistema e do código para economizar poucos bytes de espaço por registro. Parece uma otimização prematura, hein?
No Ruby você não obtém nenhuma performance, legibilidade de código, menor espaço de armazenamento / memória, normalização de dados, boa interface de consulta. Não há, literalmente, nenhuma vantagem.
@sheerun eu tenho uma tabela dedicada às configurações dos usuários com dezenas de colunas booleanas e tantas linhas como usuários. Isso me assusta. Eu prefiro muito um único campo inteiro na tabela de usuários.
& # x000A; eu nunca preciso fazer uma consulta sobre eles, eu só preciso verificar as configurações de um determinado registro.
Agora, para ser claro, nunca disse que as pessoas deveriam usar essa técnica cegamente. Todos devem ser sensíveis a como ele se encaixa nesses requisitos. Assim como tudo o resto.
& # x000A; Além disso, usei ruby ​​aqui para ilustrar o ponto, mas a publicação foi principalmente destinada a mostrar a técnica ao invés da linguagem usada para aplicá-la.
Uma vez, trabalhei na empresa, que estava licenciando um produto conectado a um banco de dados proprietário de terceiros, que quase não controlávamos. Havia uma tabela em particular que precisava de duas colunas de tipos inteiros adicionais. Com apenas uma coluna de "reposição" na tabela, sugeri que usássemos um valor ponderado para resolver o problema.
Não é uma idéia antiga, mas uma para lembrar "just-in-case".
Devo também salientar que o código que lidava com esses valores era mais difícil de ler. O Bit Shifting é um conceito fácil de entender, mas a menos que você esteja trocando bit durante todo o dia, é obrigado a diminuir a velocidade de alguns desenvolvedores e torná-los a uma pausa maior do que eles precisam para resolver um problema na produção.
Alguns métodos de tipo wrapper de conveniência acrescentariam valor.
O endianness se torna um problema com esse tipo de abordagem?
Quando você tem 65 funções + (64 bits / 8 = 8 bytes), será de maneira errada. Como o MySQL possui somente 8bytes (tipo de dados BIGINT). Como corrigi-lo ?

Opções de máscara binária
(página atual) / caixa de busca do foco.
Побитовые операторы.
Побитовые операторы позволяют считывать и устанавливать конкретные биты целых чисел.
Побитовый сдвиг в PHP - это арифметическая операция. Биты, сдвинутые за границы числа, отбрасываются. Сдвиг влево дополняет число нулями справа, сдвигая в то же время знаковый бит числа влево, что означает что знак операнда не сохраняется. Сдвиг вправо сохраняет копию сдвинутого знакового бита слева, что означает что знак операнда сохраняется.
Используйте скобки для обеспечения необходимого приоритета операторов. Например, $ a & amp; $ b == true сначала проверяет на равенство, а потом выполняет побитовое и; тогда как ($ a & amp; $ b) == true сначала выполняет побитовое и, а потом выполняет проверку на равенство.
Если оба операдна для & amp; , | и ^ строки, то операция будет производиться с кодами ASCII всех символов строки и в результате вернет строку. Во всех остальных случаях, оба операнда будут преобразованы к целому и результатом будет целое число.
Если операнд для.
Оба операнда и результат выполнения & lt; & lt; и & gt; & gt; всегда считаются за целое.
Пример # 1 Побитовыми операции И, ИЛИ и ИСКЛЮЧАЮЩЕЕ ИЛИ (E, OU и XOR) над целыми числами.
* Не обращайте внимания на этот верхний раздел кода,
* это просто форматирование для более ясного вывода.
результат значение оп тест.
* Вот сами примеры.
foreach ($ valores como $ value)
$ result = $ value & amp; $ teste;
printf ($ format, $ result, $ value, '& amp;', $ test);
foreach ($ valores como $ value)
$ result = $ value | $ teste;
printf ($ format, $ result, $ value, '|', $ test);
foreach ($ valores como $ value)
$ result = $ value ^ $ test;
printf ($ format, $ result, $ value, '^', $ test);
Результат выполнения данного примера:
Пример # 2 Побитовая операция ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) над строками.
eco 12 ^ 9; // Выводит '5'
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = # 8.
Пример # 3 Побитовый сдвиг над целыми числами.
p ($ res, $ val, '& gt; & gt;', $ places, 'слева была вставлена ​​копия знакового бита');
p ($ res, $ val, '& gt; & gt;', $ places, 'биты были выдвинуты за правый край');
p ($ res, $ val, '& gt; & gt;', $ places, 'то же, что и выше; нельзя сдвинуть дальше 0');
echo "\ n --- СДВИГ ВПРАВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- \ n";
p ($ res, $ val, '& gt; & gt;', $ places, 'слева была вставлена ​​копия знакового бита');
p ($ res, $ val, '& gt; & gt;', $ places, 'биты были выдвинуты за правый край');
p ($ res, $ val, '& gt; & gt;', $ places, 'то же, что и выше; нельзя сдвинуть дальше -1');
echo "\ n --- СДВИГ ВЛЕВО НАД ПОЛОЖИТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- \ n";
p ($ res, $ val, '& lt; & lt;', $ places, 'правый край был дополнен нулями');
$ places = (PHP_INT_SIZE * 8) - 4;
$ places = (PHP_INT_SIZE * 8) - 3;
p ($ res, $ val, '& lt; & lt;', $ places, 'знаковые биты были выдвинуты');
$ places = (PHP_INT_SIZE * 8) - 2;
p ($ res, $ val, '& lt; & lt;', $ places, 'биты были выдвинуты за левый край');
echo "\ n --- СДВИГ ВЛЕВО НАД ОТРИЦАТЕЛЬНЫМИ ЦЕЛЫМИ ЧИСЛАМИ --- \ n";
p ($ res, $ val, '& lt; & lt;', $ places, 'правый край был дополнен нулями');
$ places = (PHP_INT_SIZE * 8) - 3;
$ places = (PHP_INT_SIZE * 8) - 2;
p ($ res, $ val, '& lt; & lt;', $ places, 'биты были выдвинуты за левый край, включая знаковый бит');
* Не обращайте внимания на этот нижний раздел кода,
* это просто форматирование для более ясного вывода.
$ format = '% 0'. (PHP_INT_SIZE * 8). "b \ n";
printf ("val =% d \ n", $ val);
printf ("res =% d \ n", $ res);
printf ('val ='. $ format, $ val);
printf ('res ='. $ format, $ res);
echo "ЗАМЕЧАНИЕ: $ note \ n";
Tradução automática limitada: 32-битных машинах:
Результат выполнения данного примера на 64-битных машинах:
В PHP äî версии 7,0 никогда не используйте отрицательный побитовый сдвиг, либо сдвиг превышающий разрядность операционной системы - это может привести к неопределенному результату. Другими словами, не сдвигайте больше чем на 31 бит на 32-битных системах и больше чем на 63 бита на 64-битных.
Используйте функции из расширения gmp для побитовых операций над числами, большими чем PHP_INT_MAX .
User Contributed Notes 45 notes.
* Note: these functions are protected to prevent outside code.
* from falsely setting BITS. See how the extending class 'User'
protected function isFlagSet ( $flag )
return (( $this -> flags & $flag ) == $flag );
const FLAG_REGISTERED = 1 ; // BIT #1 of $flags has the value 1.
const FLAG_ACTIVE = 2 ; // BIT #2 of $flags has the value 2.
const FLAG_MEMBER = 4 ; // BIT #3 of $flags has the value 4.
const FLAG_ADMIN = 8 ; // BIT #4 of $flags has the value 8.
return $this -> isFlagSet ( self :: FLAG_REGISTERED );
return $this -> isFlagSet ( self :: FLAG_ACTIVE );
return $this -> isFlagSet ( self :: FLAG_MEMBER );
return $this -> isFlagSet ( self :: FLAG_ADMIN );
$this -> setFlag ( self :: FLAG_REGISTERED , $value );
$this -> setFlag ( self :: FLAG_ACTIVE , $value );
$this -> setFlag ( self :: FLAG_MEMBER , $value );
$this -> setFlag ( self :: FLAG_ADMIN , $value );
( $this -> isRegistered () ? 'REGISTERED' : '' ) .
$user -> setRegistered ( true );
$user -> setActive ( true );
$user -> setMember ( true );
$user -> setAdmin ( true );
function bitxor ( $str , $key )
$xorWidth = PHP_INT_SIZE * 8 ;
$o1 = str_split ( $str , $xorWidth );
$o2 = str_split ( str_pad ( '' , strlen ( $str ), $key ), $xorWidth );
$runs = count ( $o1 );
$res .= decbin ( bindec ( $o1 [ $i ]) ^ bindec ( $o2 [ $i ]));
$ford = $hasFourWheels | $hasDoors ;
$ferrari = $hasFourWheels | $hasDoors | $hasRedColour ;
$isGolfBuggy = $hasFourWheels & $golfBuggy ; # True, because $golfBuggy has four wheels.
$isFord = $hasFourWheels & $ford ; # True, because $ford $hasFourWheels.
$administrator = $writePost | $readPosts | $deletePosts | $addUser | $deleteUser ;
$moderator = $readPost | $deletePost | $deleteUser ;
$writer = $writePost | $readPost ;
function checkPermission ( $user , $permission )
if( $user & $permission )
if( checkPermission ( $administrator , $deleteUser ))
deleteUser ( "Some User" ); # This is executed because $administrator can $deleteUser.
Infinite* bits and bit handling in general.
the maximum limit of the index number, on 32 bit integer systems 2^31 - 1,
so 2^31 * 31 - 1 = 66571993087 bits, assuming floats are 64 bit or something.
I'm sure that's enough enough bits for anything.. I hope :D.
protected $bitmask = array();
$key = (int) ( $bit / INTEGER_LENGTH );
$bit = (int) fmod ( $bit , INTEGER_LENGTH );
$key = (int) ( $bit / INTEGER_LENGTH );
$bit = (int) fmod ( $bit , INTEGER_LENGTH );
if(! $this -> bitmask [ $key ])
unset( $this -> bitmask [ $key ]);
$key = (int) ( $bit / INTEGER_LENGTH );
$bit = (int) fmod ( $bit , INTEGER_LENGTH );
if(! $this -> bitmask [ $key ])
unset( $this -> bitmask [ $key ]);
$key = (int) ( $bit / INTEGER_LENGTH );
$bit = (int) fmod ( $bit , INTEGER_LENGTH );
return $this -> bitmask [ $key ] & ( 1 << $bit );
$this -> bitmask = array();
$array = str_split ( strrev ( $string ), INTEGER_LENGTH );
foreach( $array as $key => $value )
if( $value = bindec ( strrev ( $value )))
$this -> bitmask [ $key ] = $value ;
sort ( $keys , SORT_NUMERIC );
if( $this -> bitmask [ $i ])
$string .= sprintf ( "%0" . INTEGER_LENGTH . "b" , $this -> bitmask [ $i ]);
$this -> bitmask = array();
var_dump ( $this -> bitmask );
$bitmask = new bitmask ();
$a 0 0 0 0 1 0 0 1 =9.
$b 0 0 0 0 1 0 1 0 =10.
$a 0 0 1 0 0 1 0 0 =36.
$b 0 1 1 0 0 1 1 1 =103.
the only bits these two share together are the bits 32 and 4 which when added together return 36.
$a 0 0 0 0 1 0 0 1 =9.
$b 0 0 0 0 1 0 1 0 =10.
3 bits set, in the 8, 2, and 1 column. add those up 8+2+1 and you get 11.
$a 0 0 0 0 1 0 0 1 =9.
$b 0 0 0 0 1 0 1 0 =10.
the 2 bit and the 1 bit that they each have set but don't share. Soooo 2+1 = 3.
// We want to know the red, green and blue values of this color :
$green = ( $color & 0x00FF00 ) >> 8 ;
$blue = $color & 0x0000FF ;
$red , $red , $green , $green , $blue , $blue ) ;
// Red : FE (254), Green : A9 (169), Blue : 46 (70)
define ( "f0" , 0x1 ); // 2^0.
define ( "f1" , 0x2 ); // 2^1.
define ( "f2" , 0x4 ); // 2^2.
define ( "f3" , 0x8 ); // 2^3.
define ( "f4" , 0x10 ); // 2^4.
define ( "f5" , 0x20 ); // 2^5.
define ( "f20" , 0x1000000 ); // 2^20.
define ( "f21" , 0x2000000 ); // 2^21.
define ( "f22" , 0x4000000 ); // 2^22.
define ( "f23" , 0x8000000 ); // 2^23.
define ( "f24" , 0x10000000 ); // 2^24.
$a1 = $a & 0x7FFF0000 ;
$a2 = $a & 0x0000FFFF ;
$a3 = $a & 0x80000000 ;
$b1 = $b & 0x7FFF0000 ;
$b2 = $b & 0x0000FFFF ;
$b3 = $b & 0x80000000 ;
echo "<br>This is the value we want" ;
echo "<br>" . unsigned_xor32 ( $x , $y );
echo masksOf ( 3 , 10 );
$u = pow ( 2 , $bits )- 1 ; //start value, full flags on.
if ( $z == $n ) array_push ( $masks , $u );
bindec ( substr ( $binary , $bits ). substr ( $binary , 0 , $bits ))
var_dump ( $foo << 1 ); // Output is int(2)
var_dump ( $foo << 1 ); // Output is int(0)
not having much experience with bitwise operations, I cannot tell you that this is the BEST solution, but it certainly is a solution that finally works and always returns the EXACT same result Perl provides.
function binxor($a, $b)
return bindec(decbin((float)$a ^ (float)$b));
$result = 3851235679 ^ 43814; //= -443704711.
$result = binxor(3851235679, 43814); //= 3851262585.
$a = 3851235679 XOR 43814;
$b = 3851235679 ^ 43814; //integer result.
$c = (float)3851235679 ^ (float)43814; //same as $b.
$d = binxor(3851235679, 43814); //same as Perl!!
$mask = 0x7fffffff ; //Mask to cater for the fact that PHP only does arithmatic right shifts and not logical i. e. PHP doesn't give expected output when right shifting negative values.
$num =( $num << $offset % 32 ) | (( $num >>( 32 - $offset % 32 )) & ( $mask >>( 31 - $offset % 32 )));
elseif ( $offset < 0 )
$offset = abs ( $offset );
$num =(( $num >> $offset % 32 ) & ( $mask >>(- 1 + $offset % 32 ))) | ( $num <<( 32 - $offset % 32 ));
It is not irrelevant to point out that the decimal character's ASCII value have different binary values.
echo ord ( '18' ); //return decimal value 49, which have binary value 110001.
echo ord ( '32' ); //return decimal value 51, which have binary value 110011.
echo ord ( '10' ); //return decimal value 49, which have binary value 110001.
//Therefore 110001 & 110011 = 110001.
FE. 0xff >> -2 results in 0x0.
and 0xff << -2 result in 0xFFFFFFFFC0000000 (dependant on PHP_INT_MAX)
It's very important if you want to write a function similar to the assembly instructions 'ror' and 'rol' (Rotate on Right and Rotate on Left), because of dword value; rotating the binary always takes 32 positions and includes the leading zeros!
So this is the right way:
$binary = str_pad ( $binary , 32 , '0' , STR_PAD_LEFT );
bindec ( substr ( $binary , $bits ). substr ( $binary , 0 , $bits ))
But your code returns 0x0d9bf561 (binary: 1101100110111111010101100001)
In order to get the right value you have to add the leading zeros by adding that line with strpad() (see above). Muito importante!
) and negative binary numbers can be confusing.
2 = -3 because you use the formula.
x = - x - 1 The bitwise complement of a decimal number is the negation of the number minus 1.
1) convert the positive version of the decimal number into binary (ie: 3 = 0011)
2) flips the bits (ie: 0011 becomes 1100)
3) add 1 (ie: 1100 + 0001 = 1101)
$bin = str_pad(base_convert($number, 10, 2), 32, 0, STR_PAD_LEFT);
return ( $var >> $amt ) | $mask ;
var_dump ( 1234 ^ 0 ); // int(1234)
var_dump ( 1234 ^ '' ); // int(1234)
var_dump ( 1234 ^ null ); // int(1234)
var_dump ( 'hello world' ^ 0 ); // int(0)
var_dump ( 'hello world' ^ '' ); // string(0) ""
var_dump ( 'hello world' ^ null ); // int(0)
1) they they are both strings ,
2) "&" operator works on strings by taking each! Character! from each string and make a bit wise & between them and add this value to the resulting string.
"18" is made up of two characters: 0x31, 0x38.
"32" is made up of two characters: 0x33, 0x32.
$r = $dec & hexdec ( 'FF0000' ); //Mask for red.
$g = $dec & hexdec ( '00FF00' ); //Mask for green.
$b = $dec & hexdec ( '0000FF' ); //Mask for blue.
$rgb = hex2rgb ( '112233' );
echo "red: " . $rgb [ 0 ]. "\n" ;
echo "green: " . $rgb [ 1 ]. "\n" ;
echo "blue: " . $rgb [ 2 ]. "\n" ;
return (int)base_convert(strrev(str_pad(base_convert($n, 10, 2), PHP_INT_SIZE * 8, 0, STR_PAD_LEFT)), 2, 10);
echo "!bin & 3: " . decbin($notbin_2) . "\n";
2 == -3. There are plenty of good explanations of two's complement online, so I won't go into that question here.
if( $number < 2147483647 )
return ($number & $comparison)==$comparison;
for( $i=0; $i<strlen($binComparison); $i++ )
$x = $x ^ 0x7FFFFFFF;
$userlevel = $session -> userlevel - 0 ; # the subtraction ensures int type.
$pg_code = pow ( 2 ,( $pg_id - 1 ));
$pg_code = $pg_code / pow ( 2 , 31 );
$userlevel = $session -> userlevel / pow ( 2 , 31 ) ;
if (!( $userlevel - 0 & $pg_code ))
#if not authorized, show the unauthorized page.
header ( 'Location: Unauthorized. php' );
function sub_bindata ( $mybindata , $firstbit = 7 , $lastbit = 0 , $highestbitfirst = true )
// 1. Create a bit mask of the right size by triming left and right.
// 2. select bits by an AND on $mybindata.
// 3. shift right to get only length needed.
if( $highestbitfirst ) return ((( 0x7FFFFFFF >> ( 30 + $lastbit - $firstbit ))<<( $lastbit )) & $mybindata ) >> ( $lastbit );
else return ((( 0x7FFFFFFF >> ( 30 - $lastbit + $firstbit ))<<( 30 - $lastbit )) & $mybindata ) >> ( 30 - $lastbit );
$value = ( $value << $amount ) | ( $value >>( 32 - $amount ));
$amount = - $amount % 32 ;
$value = ( $value >> $amount ) | ( $value <<( 32 - $amount ));
$mask = ( $bits < 32 ) ? 0x7fffffff >> ( 31 - $bits ) : 0xffffffff ;
$value = ( $value << $amount ) | ( $value >>( $bits - $amount ));
$amount = - $amount % $bits ;
$value = ( $value >> $amount ) | ( $value <<( $bits - $amount ));
return $value & $mask ;
$value = bitRotate ( $test ,- $i , 8 ); // rotates 8 bits to the left (-$amount)
echo sprintf ( "%032b<br/>" , $value );
if ($bits==0) return $x;
if ($bits==32) return 0;
if ($bits==0) return $x;
if ($bits==32) return 0;
return _BF_SHR32 ($x, 8 * $y) & 0xFF;
return ($x | $y) & 0xFFFFFFFF;
$y = $y & 0xFFFFFFFF;
$byte_x = _BF_GETBYTE($x, $i);
$byte_y = _BF_GETBYTE($y, $i);
$sum = $byte_x + $byte_y;
$carryforward = _BF_SHR32($sum, 8);
$result = $sum & 0xFF;
$carry = $carryforward + _BF_SHR32($sum, 8);
function isBitSet ( $bitMask , $bitMap )
return (bool) gmp_intval ( gmp_div ( gmp_and ( $bitMask , $bitMap ), $bitMask ));
function leftshift32 ( $number , $steps )
$binary = decbin ( $number ). str_repeat ( "0" , $steps );
$binary = str_pad ( $binary , 32 , "0" , STR_PAD_LEFT );
$binary = substr ( $binary , strlen ( $binary ) - 32 );
return $binary == "1" ? -( pow ( 2 , 31 ) - bindec ( substr ( $binary , 1 ))) : bindec ( $binary );
header ( 'Content-Type: text/plain' ) ;
By this I mean managing a set of options which can either be ON or OFF, where zero or more of these options may be set and each option may only be set once. (If you are familiar with MySQL, think 'set' datatype).
Note: to older programmers, this will be obvious.
function set_bitflag ( /*variable-length args*/ )
foreach( func_get_args () as $flag ) $val = $val | $flag ;
function is_bitflag_set ( $val , $flag )
return (( $val & $flag ) === $flag );
// Define your flags.
define ( 'MYFLAGONE' , 1 ); // 0001.
define ( 'MYFLAGTWO' , 2 ); // 0010.
define ( 'MYFLAGTHREE' , 4 ); // 0100.
define ( 'MYFLAGFOUR' , 8 ); // 1000.
$myflags = set_bitflags ( MYFLAGONE , MYFLAGTHREE );
Note: you can pass set_bitflags() as many flags to set as you want.
if( is_bitflag_set ( $myflags , MYFLAGTWO ))
echo "MYFLAGTWO is set!" ;
1. Write a list of your flags.
3. Define the last flag in your list as 1 times 2 to the power of <count> minus one. ( I. E. 1*2^(<count>-1) )
3. Working backwards through your list, from the last to the first, define each one as half of the previous one. You should reach 1 when you get to the first.
// Get the value from the.
// relevant submit method.
if (!isset( $_POST [ $VARIABLE ])) $_POST [ $VARIABLE ] = '' ;
$VALUE = $_POST [ $VARIABLE ];
if (!isset( $_COOKIE [ $VARIABLE ])) $_COOKIE [ $VARIABLE ] = '' ;
$VALUE = $_COOKIE [ $VARIABLE ];
if (!isset( $_GET [ $VARIABLE ])) $_GET [ $VARIABLE ] = '' ;
$VALUE = $_GET [ $VARIABLE ];
// If necessary strip the slashes.
// the "GPC" means - GET, POST.
$VALUE = stripslashes ( $VALUE );
// Now for the different types.
$VALUE = (int) $VALUE ;
$VALUE = strtolower ( $VALUE );
$VALUE = strip_tags ( $VALUE );
$VALUE = trim ( $VALUE );
// Finally return the value.
// Convert to an Integer.
// Trim Whitespace and Strip HTML tags.
// Strip HTML tags and convert to lower case.
// If this script was loaded under the URL.
2 + 4 = 6 (Strip HTML + Convert to lower case)
if( round ( $num )== $num )
if( Isdec ( $number ))
$decimal = substr ( $number , ( strlen ( $number ) - round ( $number ) + 1 ));
$decimal *= pow ( 10 , strlen ( $decimal ) - 1 );
$Shiftl = ( $number << $amount ) + (( $decimal << $amount ) / pow ( 10 , strlen ( $decimal )));
$Shiftl = $number << $amount ;
if( Isdec ( $number ))
$decimal = substr ( $number , ( strlen ( $number ) - round ( $number ) + 1 ));
$decimal *= pow ( 10 , strlen ( $decimal ) - 1 );
$Shiftr = ( $number >> $amount ) + (( $decimal >> $amount ) / pow ( 10 , strlen ( $decimal )));
$Shiftr = $number >> $amount ;
Anyway, it's just shoving parameters in to an equation, but sometimes reinventing the wheel and putting rockets on it is a good thing.
XNOR is very usefull ;D.
is not a way to test for four-way equality. If a is zero, it'll always be true, and in general it will be true any time a has no bits not also in the other three values.

No comments:

Post a Comment