la lógica de programación Java (27) - Análisis de envasado (en)

En esta sección se sigue investigando el embalaje, introduce la clase Integer, bajo la sección Clases de caracteres, Entero largo y similares, ya no es una presentación separada, otras clases básicas se han introducido, no repetirlos.

Lo que un simple entero a introducirlo? Tiene unas operaciones binarias, observamos, además, también analizamos su valueOf logra.

¿Por qué debemos cuidar sobre el código que lo implementa? En la mayoría de los casos, no me importa, vamos a ser capaces de usarlo, que sobre todo para aprender, especialmente cuando la operación binaria, es la base de la computadora binaria, pero el código es a menudo oscura, que queremos que tengan una mayor para borrar una comprensión profunda.

Echemos un vistazo al flip bits.

flip bits

uso

Número entero tiene dos métodos estáticos que puede dar la vuelta bits:

int public static inversa (int i) 
reverseBytes int public static (int i)

Bits de la moneda es un int como binarios, bit por bit a la derecha de la izquierda intercambiables, inversa es poco intercambiables, reverseBytes es intercambiable por byte. Echemos un vistazo a un ejemplo:

Copiar el código
int a = 0x12345678; 
System.out.println (Integer.toBinaryString (a)); 

int r = Integer.reverse (a); 
System.out.println (Integer.toBinaryString (r)); 

int rb = Integer.reverseBytes (a); 
System.out.println (Integer.toHexString (rb));
Copiar el código

 a es un número entero, hexadecimal asignado, cadena binaria que es de salida primero, entonces la inversa da salida a un binario, reverseBytes hexadecimales de salida final, como salida:

10010001101000101011001111000 
11110011010100010110001001000 
78563412

reverseBytes se invierte bytes, una representación hexadecimal de 78 bytes, que es 12, por lo que el resultado es 78563412 más fácil de entender.

flip binaria a primera vista es erróneo, ya que la salida no es 32, 0:00 ignorado salida anterior, nos llena Look 32:

00010010001101000101011001111000 
00011110011010100010110001001000

Los resultados de la derecha.

Estos dos métodos son cómo lograrlo?

reverseBytes

Mira código reverseBytes:

Copiar el código
reverseBytes int public static (int i) { 
    return ((i >>> 24)) | 
           ((i >> 8) y 0xFF00) | 
           ((i << 8) y 0xFF0000) | 
           ((i << 24)); 
}
Copiar el código

Parámetro i es igual a 0x12345678, por ejemplo, se analiza el proceso de implementación:

i >>> 24 sin signo de desplazamiento a la derecha, el byte más alto se trasladó al bit más bajo, el resultado es 0x00000012.

(I >> 8) y 0xFF00, se trasladó a la izquierda del segundo byte a la derecha de la segunda, i >> 8 resultado 0x00123456, a continuación, y 0xFF00, se reserva a la derecha del segundo byte, el resultado es 0x00003400.

(I << 8) y 0xFF0000, se trasladó a la parte derecha del segundo byte de la segunda a la izquierda, i << 8 resultado 0x34567800, a continuación, y 0xFF0000, se reserva a la derecha del tercer byte, el resultado es 0x00560000.

i << 24, el resultado es 0x78000000, la izquierda y la derecha más bytes más movido.

Los cuatro resultados o las operaciones luego |, el resultado es 0x78563412, así también por izquierda, derecha y operaciones y, o, para lograr el propósito de bytes invierte.

marcha atrás

Nos fijamos en el código inverso:

Copiar el código
int public static inversa (int i) { 
    // HD, Figura 7-1 
    I = (I & 0x55555555) << 1 | (i >>> 1) y 0x55555555; 
    i = (I & 0x33333333) << 2 | (i >>> 2) y 0x33333333; 
    i = (I & 0x0f0f0f0f) << 4 | (i >>> 4) y 0x0f0f0f0f; 
    i = (i << 24) | ((I & 0xff00) << 8) | 
        ((i >>> 8) y 0xff00) | (i >>> 24); 
    i volver; 
}
Copiar el código

Aunque este código es muy corto, pero muy oscuro, al final, ¿qué significa?

La primera línea es un comentario, "HD, Figura 7-1," ¿Qué significa? HD está representado por un libro llamado Delight de Hacker, HD sus siglas, la figura 7-1 es un diagrama para 7-1 libro, el libro, el contenido, como se muestra a continuación:

Como puede verse, de enteros en el código inversa es una copia del libro del código de la Figura 7-1, el código interpretado a la figura también muestra, que traducirlo.

La idea básica de la tapa eficiente bit implementación, intercambio de bits única adyacente primero, y luego como un grupo de dos, entonces el intercambio de bits adyacentes, seguido por un grupo de cuatro de conmutación, a continuación, ocho, dieciséis, dieciséis después de que el bit es completa. Esta idea se aplica no sólo a binario, decimal, también es aplicable, para facilitar la comprensión, buscamos ejemplos decimales, como el desplazamiento digital 12345678,

La primera ronda, el intercambiada único digital adyacente, el resultado es:

21 43 65 87

Segunda ronda, un conjunto de dos números para el intercambio de adyacente, el resultado es:

43 21 87 65

La tercera ronda, un grupo de cuatro cifras para el intercambio de adyacente, el resultado es:

8765 4321

Flip completado.

Para decimal, la eficacia no es alta, pero para binario, es eficiente porque una pluralidad de bits binarios adyacentes puede ser intercambiado en una instrucción.

Esta línea es adyacente a un único intercambio:

x = (x y 0x55555555) << 1 | (X y 0xAAAAAAAA) >>> 1;

5 es 0101,0x55555555 representación binaria binario es:

01010101010101010101010101010101

X & 0x55555555 es tomar el bit impar de x.

Un binario es 1010,0xAAAAAAAA representación binaria es:

10101010101010101010101010101010

X & 0xAAAAAAAA se toma bit de x.

(X & 0x55555555) << 1 | (X y 0xAAAAAAAA) >>> 1;

X está representado por el bit impar para los bits de la izquierda, incluso a la derecha, entonces | fusión, lograr el propósito de bits adyacentes intercambiables. Este código puede ser optimizado para tener una pequeña, solamente una constante 0x55555555, y luego la segunda mitad de la primera operación de cambio, se convierte en:

(I & 0x55555555) << 1 | (I >>> 1) y 0x55555555;

De manera similar, el siguiente código es de dos bits en un grupo de bits adyacentes son intercambiables:

i = (I & 0x33333333) << 2 | (I y 0xCCCCCCCC) >>> 2;

3 es 0011,0x33333333 representación binaria binario es:

00110011001100110011001100110011 

x x y 0x33333333 es tomar dos de la mitad inferior de un conjunto.

C es la representación binaria 1100,0xCCCCCCCC binario es:

11001100110011001100110011001100

x x y 0xCCCCCCCC es tomar parte en dos de media altura en un conjunto.

(I & 0x33333333) << 2 | (I y 0xCCCCCCCC) >>> 2;

X se representa como un conjunto de dos, la mitad inferior a la mitad inferior de la alta desplazamiento desplazada, alto, entonces | combinada, lograr el propósito de intercambio. Del mismo modo, la constante se puede quitar 0xCCCCCCCC, el código puede ser optimizado para:

(I & 0x33333333) << 2 | (I >>> 2) y 0x33333333;

De manera similar, el siguiente código es el grupo de cuatro bits, se intercambian.

i = (I & 0x0f0f0f0f) << 4 | (I >>> 4) y 0x0f0f0f0f;

El aparato se pone en octetos, es decir, bytes invierte, se puede escribir de la siguiente manera una forma más directa, y reverseBytes códigos sustancialmente idénticas.

i = (i << 24) | ((I & 0xff00) << 8) | 
    ((i >>> 8) y 0xff00) | (i >>> 24);

¿Por qué escribir el código inverso, de modo que oscurecer? O escritura no puede ser más fácil de entender la forma de la misma? Por ejemplo, para lograr lado, una idea común es, primero y último intercambio, la segunda y penúltima de intercambio hasta que el medio de los dos se ha completado el intercambio. Si los datos no son bits binarios, la idea es buena, pero para los bits, el rendimiento es relativamente bajo.

instrucciones de la CPU y el funcionamiento eficiente no puede ser un solo bit, la unidad más pequeña de datos que es típicamente operación de 32 bits (máquinas de 32 bits), el cambio Además, la CPU puede ser implementado de manera eficiente y operaciones lógicas, pero más lentamente Math.

revertir estas características es la utilización de CPU completo, realizado en cambio paralelo y eficiente de bits adyacentes, la misma función se puede conseguir también en otras formas más fáciles de entender, pero esto es más eficiente que el código sea difícil.

desplazamiento cíclico

uso

Entero tiene dos métodos estáticos se pueden desplazar cíclicamente:

public static int rotateLeft (int i, distancia int) 
public static int rotateRight (int i, int distancia)

rotateLeft es Rotar a la izquierda, rotateRight se gira a la derecha, la distancia es el número de bits en movimiento, llamado desplazamiento cíclico, el cambio es relativa a la normal en términos del cambio general, tales como izquierda 2, la parte superior original de dos no hay derecho llenará 0, y si se desplaza a la izquierda dos ciclos, la parte superior original de dos se moverá hacia la derecha, como un anillo alrededor del mismo contacto. Echemos un vistazo a un ejemplo:

Copiar el código
int a = 0x12345678; 
int b = Integer.rotateLeft (a, 8); 
System.out.println (Integer.toHexString (b)); 

int c = Integer.rotateRight (a, 8); 
System.out.println (Integer.toHexString (c))
Copiar el código

b es un resultado circular desplazamiento a la izquierda de 8 bits, c es un desplazamiento circular derecha de 8 bits resultado, la salida es:

34567,812 mil 
78.123456 millones

código de implementación

Código que implementa estas dos funciones son:

Copiar el código
public static int rotateLeft (int i, int distancia) { 
    return (i << distancia) | (i >>> -Distancia); 
} 
Public static int rotateRight (int i, int distancia) { 
    return (i >>> distancia) | (i << -Distancia); 
}
Copiar el código

Estas dos funciones son desconcertantes es negativo, si la distancia es de 8, que >>> - 8 ¿Qué significa? De hecho, el número real más baja de cambio digital directa no está de vuelta, pero el valor digital directa de 5, o es un resultado directo de 0x1f digitales y de. La razón de esto se debe a los cinco más grandes representan el 31, desplazando a más de 31 pares de enteros int no es válido.

Entender la posición de movimiento sentido negativo, es más probable que el código anterior, por ejemplo, -8 representación binaria es:

11111111111111111111111111111000

Su menor nivel 5 es 11000, el decimal es 24, así que >>> - 8 es i >>> 24, i << 8 | i >>> 24 se gira hacia la izquierda y ocho.

Código anterior, i >>> - distancia es i >>> (de 32 a distancia), i << - distancia es i << (de 32 a distancia).

hallazgo bit a bit, el recuento

Hay otros bits Operaciones con enteros, incluyendo:

public static int signum (int i)

Comprobar el bit de signo, rendimientos positivos 1, -1, 0 0 rendimiento negativo

public static int lowestOneBit (int i)

Encuentra la derecha desde el número de posición de la primera, que se mantienen sin cambios, el otro bit se pone a 0, se devuelve el número entero. 3 Por ejemplo, binario 11, resultado binario es 01, el decimal es 1, por 20, es decir 10 100 binario, el resultado es 00100, es 4 decimal.

public static int highestOneBit (int i) 

Mirando desde la izquierda de la primera posición del número 1, que se mantienen sin cambios, el otro bit se pone a 0, se devuelve el número entero.

public static int bitCount (int i)  

Encuentra la representación binaria del número 1. 20 Por ejemplo, un número binario es 2 10100,1.

numberOfLeadingZeros int public static (int i)

A partir de la izquierda es el número de cero consecutivo. 20 Por ejemplo, el binario es 10100, izquierda 27 0.

numberOfTrailingZeros int public static (int i)

El extremo derecho es el número de consecutivos de 0. 20 Por ejemplo, el binario es 10100, a la derecha hay dos cero.

Sobre la realización del código, hay comentarios dirigidos Delight capítulos pertinentes del Hacker de este libro, no repetirlos.

La realización valueOf

Cuando mencionamos en la sección anterior, crear un objeto de clase de contenedor, puede utilizar el método valueOf estática, también se puede utilizar el nuevo directo, pero se recomienda utilizar valueOf, ¿por qué? Buscamos código valueOf:

Copiar el código
public static Entero valueOf (int i) { 
    afirman IntegerCache.high> = 127; 
    si (i> = IntegerCache.low && i <= IntegerCache.high) 
        regrese IntegerCache.cache [i + (-IntegerCache.low)]; 
    volver new Integer (i); 
}
Copiar el código

Utiliza IntegerCache, que está dentro de un código de clase estática privada de la siguiente manera:

Copiar el código
clase estática privada IntegerCache { 
    static final int bajo = -128; 
    estática alta int final; 
    caché Entero static final []; 

    estática { 
        // alto valor puede ser configurado por la propiedad 
        int h = 127; 
        Cadena integerCacheHighPropValue = 
            sun.misc.VM.getSavedProperty ( "java.lang.Integer.IntegerCache.high"); 
        si (integerCacheHighPropValue! = null) { 
            int i = parseInt (integerCacheHighPropValue); 
            i = Math.max (i, 127); 
            // máximo tamaño de la matriz es Integer.MAX_VALUE 
            h = Math.min (i, Integer.MAX_VALUE - (-baja) -1); 
        } 
        Alta = h;

        cache = new Integer [(alto - bajo) + 1]; 
        int j = baja; 
        for (int k = 0; k <cache.length; k ++) 
            caché [k] = new Integer (j ++); 
    } 

    IntegerCache privada () {} 
}
Copiar el código

IntegerCache entero que representa la memoria caché, en el que la memoria caché es una matriz estática de variables enteras se inicializa en la estática inicializador bloque, por defecto, un almacenamiento 127, un total de 256 que corresponde a un número entero de -128 a un objeto Integer.

En el código valueOf, si el valor está en el rango de caché de -128 a 127, que es el valor predeterminado, entonces el objeto pre-adquirido Entero creado directamente desde el IntegerCache, no sólo la gama de la memoria caché, el objeto no se crea por la nueva.

Al compartir objetos comunes, se puede ahorrar espacio de memoria, ya Entero es inmutable, que se almacena en caché los objetos con seguridad pueden ser compartidos. Boolean / bytes / corta / larga / personaje tiene una aplicación similar. Este objetivo común de intercambio de pensamiento, es una ideas de diseño comunes, en <Modo Diseño> esto funciona, se le da un nombre, se llama peso mosca, el Inglés llamado peso mosca, es decir, la proporción de elementos ligeros.

resumen

En esta sección se describen algunas de operación en poco Entero, el código de operación de bit más oscuro, pero el rendimiento es relativamente alta, se explica en detalle algunas código que, si quieres saber más, de acuerdo a los comentarios, ver Delight este libro de Hacker. También hemos introducido la realización valueOf, introduce el patrón de peso mosca.

En la siguiente sección, vamos a explorar Carácter

Supongo que te gusta

Origin www.cnblogs.com/ivy-xu/p/12584571.html
Recomendado
Clasificación