Você provavelmente está familiarizado com a palavra “batida”. Se não, vamos conhecer :) Um bit é a unidade mínima de medida de informação em um computador. Seu nome vem do inglês “ dígito binário ” – “número binário”. Um bit pode ser expresso como um de dois números: 1 ou 0. Existe um sistema numérico especial baseado em uns e zeros - binário. Não nos aprofundaremos na selva da matemática e apenas observaremos que qualquer número em Java pode ser convertido para sua forma binária. Para fazer isso, você precisa usar classes wrapper. Por exemplo, veja como fazer isso para um número
Todas as operações são realizadas da esquerda para a direita, mas tendo em conta a sua prioridade. Por exemplo, se escrevermos:
int
:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(x));
}
}
Saída do console:
101010110
1010 10110 (adicionei um espaço para facilitar a leitura) é o número 342 em binário. Na verdade, dividimos esse número em bits individuais - zeros e uns. É com eles que podemos realizar operações chamadas bit a bit.
-
~
- operador “NÃO” bit a bit.
00000000 00000000 00000001 01010110
- o número 342 em uma variável do tipo int em java 11111111 11111111 11111110 10101001
- o resultado da expressão ~342 em java Vamos tentar fazer isso na prática:
public class Main {
public static void main(String[] args) {
int x = 342;
System.out.println(Integer.toBinaryString(~x));
}
}
Saída do console:
11111111111111111111111010101001
-
&
- operador bit a bit “AND”
&&
). O operador &&
, como você lembra, retorna true
apenas se ambos os operandos forem verdadeiros. Bitwise &
funciona de maneira semelhante: compara dois números bit a bit. O resultado dessa comparação é o terceiro número. Por exemplo, tomemos os números 277 e 432: 100010101 - o número 277 na forma binária 110110000 - o número 432 na forma binária A seguir, o operador &
compara o primeiro bit do número superior com o primeiro bit do número inferior. Por se tratar de um operador “AND”, o resultado será igual a 1 somente se ambos os bits forem iguais a 1. Em todos os outros casos, o resultado será 0. 100010101 &
110110000 _______________ 100010000 - resultado do trabalho &
Primeiro comparamos os primeiros bits de dois números entre si, depois os segundos bits, o terceiro, etc. Como você pode ver, apenas em dois casos os dois bits dos números foram iguais a 1 (o primeiro e o quinto bits). O resultado de todas as outras comparações foi 0. Portanto, no final obtivemos o número 100010000. No sistema decimal, corresponde ao número 272. Vamos verificar:
public class Main {
public static void main(String[] args) {
System.out.println(277&432);
}
}
Saída do console:
272
|
- “OU” bit a bit. O princípio de operação é o mesmo - comparamos dois números aos poucos. Só que agora se pelo menos um dos bits for igual a 1, o resultado será igual a 1. Vejamos os mesmos números - 277 e 432:
|
110110000 _______________ 110110101 - o resultado do trabalho |
Aqui o resultado é diferente: apenas os bits que eram zeros em ambos os números permaneceram zeros. O resultado do trabalho é o número 110110101. No sistema decimal corresponde ao número 437. Vamos verificar:
public class Main {
public static void main(String[] args) {
System.out.println(277|432);
}
}
Saída do console:
437
Contamos tudo corretamente! :)
^
- OR exclusivo bit a bit (também conhecido como XOR)
true
se pelo menos um operando for verdadeiro. Mas não necessariamente um – se ambos existirem true
– então o resultado true
. Mas o “ou” exclusivo retorna true
apenas se um dos operandos for verdadeiro. Se ambos os operandos forem verdadeiros, um “ou” regular retornará true
(“pelo menos um é verdadeiro”), mas um ou exclusivo retornará false
. É por isso que é chamado de exclusivo. Conhecendo o princípio das operações bit a bit anteriores, você provavelmente poderá executar facilmente a operação 277 ^ 432 sozinho. Mas é melhor descobrirmos juntos mais uma vez :) 100010101 ^
110110000 _______________ 010100101 - o resultado do trabalho ^
Aqui está o nosso resultado. Os bits iguais em ambos os números retornaram 0 (a fórmula “um de” não funcionou). Mas aqueles que formaram um par 0-1 ou 1-0 acabaram virando uma unidade. Como resultado, obtivemos o número 010100101. No sistema decimal corresponde ao número 165. Vamos ver se calculamos corretamente:
public class Main {
public static void main(String[] args) {
System.out.println(277^432);
}
}
Saída do console:
165
Super! Tudo está exatamente como pensamos :) Agora é a hora de nos familiarizarmos com as operações chamadas bit shifts. O nome, em princípio, fala por si. Pegaremos algum número e moveremos seus bits para a esquerda e para a direita :) Vamos ver como fica:
Deslocar para a esquerda
O deslocamento de bits para a esquerda é indicado pelo sinal<<
Exemplo:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(Integer.toBinaryString(x));
System.out.println(Integer.toBinaryString(z));
}
}
Neste exemplo, o número x=64
é chamado de valor. São seus pedaços que mudaremos. Deslocaremos os bits para a esquerda (isso pode ser determinado pela direção do sinal <<
). No sistema binário, o número 64 = 1000000 O número y=3
é chamado de quantidade. Quantidade responde à pergunta “quantos bits para a direita/esquerda os bits de um número devem ser deslocados x
?” Em nosso exemplo, iremos deslocá-los 3 bits para a esquerda. Para tornar o processo de mudança mais claro, vejamos a imagem. Em nosso exemplo usamos números do tipo int. Int
ocupam 32 bits de memória do computador. Esta é a aparência do nosso número original 64: E agora nós, no sentido literal da palavra, pegamos cada um dos nossos bits e o deslocamos 3 células para a esquerda: Foi isso que obtivemos. Como você pode ver, todos os nossos bits foram deslocados e mais 3 zeros foram adicionados fora do intervalo. 3 - porque estávamos mudando 3. Se estivéssemos mudando 10, seriam adicionados 10 zeros. Portanto, a expressão x << y
significa “deslocar os bits de um número х
y células para a esquerda”. O resultado da nossa expressão foi o número 1000000000, que no sistema decimal é igual a 512. Vamos verificar:
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 3;//quantity
int z = (x << y);
System.out.println(z);
}
}
Saída do console:
512
Isso mesmo! Em teoria, os bits podem ser deslocados indefinidamente. Mas como temos o número int
, existem apenas 32 células disponíveis. Destes, 7 já estão ocupados pelo número 64 (1.000.000). Portanto, se fizermos, por exemplo, 27 deslocamentos para a esquerda, nossa única unidade sairá do intervalo e “sobrescreverá”. Apenas zeros permanecerão!
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 26;//quantity
int z = (x << y);
System.out.println(z);
}
}
Saída do console:
0
Como esperávamos, aquele ultrapassou as células de 32 bits e desapareceu. Obtivemos um número de 32 bits que consiste apenas em zeros. Naturalmente, no sistema decimal corresponde a 0. Uma regra simples para lembrar os deslocamentos à esquerda: a cada deslocamento à esquerda, o número é multiplicado por 2. Por exemplo, vamos tentar calcular o resultado da expressão sem imagens com bits. 111111111 << 3
para multiplicar três vezes o número 111111111 por 2. Como resultado, obtemos 888888888. Vamos escrever o código e verificá-lo:
public class Main {
public static void main(String[] args) {
System.out.println(111111111 << 3);
}
}
Saída do console:
888888888
Mudanças à direita
Eles são indicados pelo sinal>>
. Eles fazem a mesma coisa, só que na outra direção! :) Não vamos reinventar a roda e tentar fazer isso com o mesmo número int 64.
public class Main {
public static void main(String[] args) {
int x = 64;//meaning
int y = 2;//quantity
int z = (x >> y);
System.out.println(z);
}
}
Como resultado do deslocamento de 2 para a direita, os dois zeros extremos do nosso número saíram do intervalo e foram apagados. Obtivemos o número 10000, que no sistema decimal corresponde ao número 16. Saída para o console:
16
Uma regra simples para lembrar deslocamentos à direita: cada deslocamento à direita divide por dois, descartando qualquer resto. Por exemplo, 35 >> 2
significa que precisamos dividir 35 por 2 2 vezes, descartando o resto 35/2 = 17
(descartando resto 1) 17:2 = 8
(descartando resto 1) O total 35 >> 2
deve ser igual a 8. Verifique:
public class Main {
public static void main(String[] args) {
System.out.println(35 >> 2);
}
}
Saída do console:
8
Precedência de operações em Java
Ao escrever ou ler código, você frequentemente encontrará expressões nas quais diversas operações são executadas simultaneamente. É muito importante entender em que ordem serão realizadas, caso contrário o resultado pode ser inesperado. Como existem muitas operações em Java, todas foram separadas em uma tabela especial:operador precedente
Operadores | Precedência |
---|---|
pós-fixado | expr++ expr-- |
unário | ++expr --expr +expr ~ ! |
Multiplicativo | * / % |
aditivo | + - |
mudança | << >> >>> |
relacional | < > <= >= instancia de |
igualdade | == != |
E bit a bit | & |
OR exclusivo bit a bit | ^ |
OU bit a bit inclusivo | | |
lógico E | && |
OU lógico | || |
ternário | ? : |
atribuição | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
int x = 6 - 4/2;
primeiro será realizada a operação de divisão (4/2). Embora ela seja a segunda na fila, ela tem maior prioridade. Parênteses ou colchetes alteram qualquer prioridade para o máximo. Você provavelmente se lembra disso da escola. Por exemplo, se você adicioná-los a uma expressão: int x = (6 - 4)/2;
a subtração será realizada primeiro, pois é calculada entre parênteses. O operador lógico tem &&
uma prioridade bastante baixa, como pode ser visto na tabela. Portanto, na maioria das vezes será executado por último. Por exemplo: boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Esta expressão seria executada assim:
-
4/2 = 2
boolean x = 6 - 2 > 3 && 12*12 <= 119;
-
12*12 = 144
boolean x = 6 - 2 > 3 && 144 <= 119;
-
6-2 = 4
boolean x = 4 > 3 && 144 <= 119;
-
A seguir serão executados os operadores de comparação:
4 > 3 = true
boolean x = true && 144 <= 119;
-
144 <= 119 = false
boolean x = true && false;
-
E finalmente, o último operador será executado
&&
.boolean x = true && false;
boolean x = false;
O operador de adição (
+
), por exemplo, tem precedência maior que o operador de comparação!=
(“diferente”);Portanto na expressão:
boolean x = 7 != 6+1;
primeiro será realizada a operação 6+1, depois a verificação 7!=7 (falso), e ao final o resultado será atribuído à
false
variávelx
. A atribuição geralmente tem a prioridade mais baixa de todas as operações – veja a tabela.
- Operadores Lógicos - Palestra JavaRush sobre operações lógicas. Não chegaremos a eles tão cedo, mas você pode lê-los agora, não haverá nenhum dano
GO TO FULL VERSION