Hay seis operadores básicos a nivel de bits: AND, OR, XOR, negación, desplazamiento a la izquierda y desplazamiento a la derecha:
Operación de ejemplo de operación de bit
Operación de bits | Caracteristicas | Ejemplo |
---|---|---|
x >> 1 | Eliminar el último dígito | 101101-> 10110 |
x << 1 | Agrega un 0 al final | 101101-> 1011010 |
x << 1 | Agrega un 1 al final | 101101-> 1011011 |
x | 1 | Cambie el último dígito a 1 | 101100-> 101101 |
x y -2 | Cambiar el último dígito a 0 | 101101-> 101100 |
x ^ 1 | El último bit está negado | 101101-> 101100 |
x | (1 << (k-1)) | Gire el kth bit de la derecha a 1 | 101001-> 101101, k = 3 |
x & ~ (1 << (k-1)) | Gire el kth bit de la derecha a 0 | 101101-> 101001, k = 3 |
x ^ (1 << (k-1)) | El késimo de la derecha está invertido | 101001-> 101101, k = 3 |
x y 7 | Toma los últimos tres | 1101101-> 101 |
x & (1 << k-1) | Toma los últimos k bits | 1101101-> 1101, k = 5 |
x >> (k-1) y 1 | Toma el kth de la derecha | 1101101-> 1, k = 4 |
x | ((1 << k) -1) | Convierte los últimos k bits en 1 | 101001-> 101111, k = 4 |
x ^ (1 << k-1) | Invertir los últimos k bits | 101001-> 100110, k = 4 |
x y (x + 1) | Convierte los 1 consecutivos de la derecha en 0 | 100101111-> 100100000 |
x | (x + 1) | Convierte el primer 0 de la derecha en 1 | 100101111-> 100111111 |
x | (x-1) | Convierte los 0 consecutivos de la derecha en 1 | 11011000-> 11011111 |
(x ^ (x + 1)) >> 1 | Toma los 1 consecutivos a la derecha | 100101111-> 1111 |
x y -x | Retire el lado izquierdo del primero 1 del derecho | 100101000-> 1000 |
x y 0x7F | Toma los últimos 7 | 100101000-> 101000 |
x & ~ 0x7F | ¿Es menos de 127 | 001111111 y ~ 0x7F-> 0 |
x & 1 | Paridad | 00000111 y 1-> 1 |
Dos consideraciones para el uso de operaciones de bits:
- Las operaciones de bit solo se pueden usar para remodelar datos. Las operaciones de bit en tipos flotantes y dobles serán reportadas por el compilador.
- La prioridad de operación de los operadores de bits es relativamente baja, porque intente usar paréntesis para asegurar el orden de las operaciones.
1. Determina si un valor es una potencia entera de 2
Ideas de resolución de problemas:
Solo hay un 1 en el bit más alto del binario correspondiente a la potencia entera de 2, como: 8, el binario es 1000; 4, el binario es 0100,
Luego reste 1 del número y realice la operación Y con el número. Después de restar 1, se obtiene el binario: 7, el binario es 0111; 3, el binario es 0011, podemos ver que 8 y 7 es 0,
4 y 3 es 0
Entonces, si n es una potencia entera de 2, entonces el resultado de n & (n-1) debe ser 0:
El valor de n debe ser mayor que 0
1. public class Main {
3. public static void main(String[] args) {
4. int n = 8;
5. if ((n & (n-1)) == 0){
6. System.out.println("整数的二次方 true");
7. }else{
8. System.out.println("不是整数的二次方");
9. }
10. }
11. }
2. Utilice la operación de bits para intercambiar dos números [No utilice variables intermedias]
XOR
1. public class Main {
3. public static void main(String[] args) {
4. int n = 8, m = 10;
5. n ^= m;
6. m ^= n;
7. n ^= m;
8. System.out.println(n + ", " + m);
9. }
10. }
Por ejemplo: a = 13, b = 6:
el binario de a es 13 = 8 + 4 + 1 = 1101 (binario)
El binario de b es 6 = 4 + 2 = 110 (binario)
- a ^ = ba = 1101 ^ 110 = 1011;
- b ^ = ab = 110 ^ 1011 = 1101; Inmediatamente b == 13
- a ^ = ba = 1011 ^ 1101 = 110; Inmediatamente a == 6
Otros métodos, usa la suma y la resta
1. public class Main {
3. public static void main(String[] args) {
4. int n = 8, m = 10;
5. n = n + m;
6. m = n - m;
7. n = n - m;
8. System.out.println(n + ", " + m);
9. }
10. }
3. Calcule cuántos 1 hay en la representación binaria de un entero de 32 bits.
Utilice x & (x-1) para eliminar el último dígito 1 y calcule cuántas veces se ha eliminado.
Como:
13: 1101
12: 1100
Fase y: 1100, eliminar el último dígito
1. public class Main {
3. public static void main(String[] args) {
4. // 计算在一个 32 位的整数的二进制表示中有多少个 1
5. int m = 13, num = 0;
6. while (true){
7. if (m == 0) break;
8. m &= (m-1);
9. num ++;
10. }
11. System.out.println(num);
12. }
14. }
4. Los números positivos se convierten en números negativos o los números negativos se convierten en números positivos
El signo de conversión solo debe invertirse y luego agregar 1
1. public class Main {
3. public static void main(String[] args) {
4. // 计算在一个 32 位的整数的二进制表示中有多少个 1
5. int m = -13;
6. int changeM = ~m + 1;
7. System.out.println(changeM);
8. }
10. }
5. Determinar la paridad de un valor.
Siempre que se decida según si el bit mínimo es 0 o 1, 0 significa número par, 1 significa número impar, por lo que solo es necesario AND 1.
Por lo tanto, si ((a & 1) == 0) se puede usar en lugar de if (a% 2 == 0) para determinar si a es par.
1. public class Main {
3. public static void main(String[] args) {
4. int m = -14;
6. if ((m & 1) == 1){
7. System.out.println("ji");
8. }else{
9. System.out.println("ou");
10. }
11. }
13. }
6. Multiplicar por 2 a la potencia de la operación m
La operación de multiplicar por 2, es decir, 2 elevado a 1 y desplazar 1 bit hacia la izquierda
System.out.println(10<<1);
Derivar la extensión:
Multiplicado por 2 elevado a m
System.out.println(10<<2); // 乘以 2的2次方,相当于乘以 4
7. Operación de división por 2 (la operación de números impares negativos no está disponible)
System.out.println(10>>1);
8. Convertir a valor absoluto
1. public class Main {
3. public static void main(String[] args) {
4. int n = 12;
6. System.out.println(0 >> 31); // 0
7. System.out.println(10 >> 31); // 0
8. System.out.println(-10 >> 31); // -1
10. System.out.println((n ^ (n >> 31)) - (n >> 31)); // 12
12. }
14. }
- Primero: n >> 31 obtiene el signo de n
Si n es un número positivo, n >> 31 es igual a 0; si n es un número negativo, n >> 31 es igual a -1. Si n es un número positivo, n ^ 0-0 no cambia;
- Si n es un número negativo n ^ -1, debe calcular el complemento de n y -1, y luego tomar el complemento después del O exclusivo. Como resultado, n cambia de signo y el valor absoluto se resta por 1, y entonces menos -1 es el valor absoluto
9. Determina si los dos números tienen el mismo signo.
verdadero significa que xey tienen el mismo signo, falso significa que xey tienen signos opuestos.
System.out.println((a ^ b) > 0);
10. Encuentra el promedio de dos enteros (int)
System.out.println((a+b) >> 1);
11. Calcula el máximo de dos números enteros
1. int max(int a,int b){
2. return b & ((a-b) >> 31) | a & (~(a-b) >> 31);
3. /*如果a>=b,(a-b)>>31为0,否则为-1*/
4. }
12. Encuentra el mínimo de dos números enteros
1. int min(int a,int b){
2. return a & ((a-b) >> 31) | b & (~(a-b) >> 31);
3. /*如果a>=b,(a-b)>>31为0,否则为-1*/
4. }
13. Suma de dos números enteros
Use ^
y para &
sumar dos enteros
- XOR de dos números: equivale a sumar dos números sin considerar el acarreo;
- Dos números se colocan en AND y se desplazan hacia la izquierda en una posición: equivalente a encontrar un acarreo;
13 + 11 =?;
13 en binario 1 1 0 1 ----- a 13
11 binario 1 0 1 1 ----- b 11
(a y b) << 1 -> 1 0 0 1 0 ----- d 18
a ^ b -> 0 1 1 0 ----- e 6
(d & e) << 1 -> 0 0 1 0 0 ------ f 4
d ^ e -> 1 0 1 0 0 ----- g 20
(f & g) << 1 -> 0 1 0 0 0 ------ h 8
f ^ g -> 1 0 0 0 0 ------ i 16
(h & i) << 1 -> 0 0 0 0 0 ------ h 0 ---- -------- No hay acarreo, luego salga del bucle
h ^ yo -> 1 1 0 0 0 ------ yo 24
1. private static int getSum(int a, int b) {
2. if (a == 0) return b;
3. if (b == 0) return a;
4. while (b != 0) {
5. int carry = a & b; // 得到有进位的位置
6. a = a ^ b; // 直接相加,但是没有进位
7. b = carry << 1; // 得到进位
8. }
9. return a;
10. }
Recomendación de proyecto:
2020 WeChat Mini Program Full-stack Project-Miaomiao Making Friends [Con cursos y código fuente]
Spring Boot desarrolla un pequeño y hermoso blog personal [con material didáctico y código fuente]