Los trucos de la computación de bits son muy interesantes ~

Hay seis operadores básicos a nivel de bits: AND, OR, XOR, negación, desplazamiento a la izquierda y desplazamiento a la derecha:

Ingrese la descripción de la imagen aquí

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:

  1. 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.
  2. 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)

  1. a ^ = ba = 1101 ^ 110 = 1011;
  2. b ^ = ab = 110 ^ 1011 = 1101; Inmediatamente b == 13
  3. 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.  }
  1. 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;

  1. 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

  1. XOR de dos números: equivale a sumar dos números sin considerar el acarreo;
  2. Dos números se colocan en AND y se desplazan hacia la izquierda en una posición: equivalente a encontrar un acarreo;

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

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:

Más de 2000 G de recursos electrónicos compartidos en diversas industrias informáticas (actualización continua)

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]

Microservicios Java de combate real 296 episodios de video a gran escala-Grain Mall [con código y material didáctico]

Microservicios de desarrollo de Java Combate real de Changbu Mall [357 episodios completos de grandes proyectos] -con código y material didáctico

El video de algoritmo y estructura de datos más completo y detallado [con material didáctico y código fuente]

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.51cto.com/14906631/2608802
Recomendado
Clasificación