Interpretación del método de tounsignedString
Vi que hay un método en entero que convierte int en una cadena de tipo sin firmar, pero hay varios puntos que no son muy claros. Después de consultar la información, la entiendo de la siguiente manera:
/*** Convierta el entero a un número sin firmar. */ cadena estática privada tounsignedString (int i, int shift) {char [] buf = new Char [32]; int charpos = 32; int radix = 1 << shift; int mask = radix - 1; do {buf [-charpos] = dígitos [i & Mask]; i >>> = shift; } while (i! = 0); return new String (BUF, CharPos, (32 - Charpos)); }El cambio de parámetro aquí representa el sistema binario. Si es binario, el cambio es 2, octal es 8 y la máscara correspondiente se calcula como 1 y 7. Extraiga continuamente los caracteres correspondientes en la matriz de dígitos a través de la máscara e i.
De esta manera, realizo una operación lógica de cambio derecho cada vez, y el bit más alto agrega cero, de modo que después del cambio de derecha lógico continuo, me convertiré en 0
Además, adoptar DO-While es evitar que la matriz de BUF obtenga su valor cuando yo es 0.
Interpretación del método de tostración
// Esta matriz representa la parte de diez dígitos del número, y esta matriz se usará a continuación. final static char [] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '9', '9', '9', '9', '9', '9' ', 9', '9',}; // Esta matriz representa la parte de un solo dígito de un número, y esta matriz se usará a continuación. If each part of the array is combined, two-digit integers can be obtained in all cases within 100. final static char [] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ',', ',' 1 '', '2', '3', '4', ',', ',', ',', ',', ', 5', ',', ',', 5 ',', ',', ',', ',', ',', '5 '7', '8', '9', '0', '1' ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ', 9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', ',' 3 ',' 5 ',' 5 ',', '5', ',', ',', ',', ',', ',', '5', '4', ',', '4', ',', ',', ',', ',', ',', ',', ',', ',', '5', ',', ',', ',', ',', ',', ','. '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',}; public static string toString (int i) {if (i == integer.min_value) // Agregar 1 aquí. Al principio, no sé lo que significa. Más tarde, si encuentro que se encuentra un número negativo, necesito agregar un signo negativo frente a él, por lo que el tamaño de la cadena debe agregarse 1.// La parte pasada en Stringsize aquí es positiva, en la matriz a continuación // map int size = (i <0)? stringsize (-i) + 1: stringsize (i); char [] buf = new Char [size]; getchars (i, tamaño, buf); devolver una nueva cadena (0, tamaño, BUF); } static void getchars (int i, int index, char [] buf) {int q, r; int charpos = index; signo de char = 0; if (i <0) {sign = '-'; i = -i; } // Para enteros superiores a 65536, primero realice el siguiente procesamiento, // En este proceso, en unidades de 100, es decir, el resto se controla en dos dígitos // Esto solo se asigna a la matriz de diez dígitos y de diez dígitos anteriores, y escribe dos dígitos en la matriz de BUF a la vez. Esto es indudablemente mucho más rápido que encontrar cada dígito, mientras que (i> = 65536) {q = i / 100; // realmente: r = i - (q * 100); r = i - ((q << 6) + (q << 5) + (q << 2)); i = Q; buf [--charpos] = digitones [r]; buf [--charpos] = digittens [r]; } // caer hasta el modo rápido para números más pequeños // afirmar (i <= 65536, i); // For integers less than or equal to 65536, the following part can be directly performed // And this place is divided by 10, but the implementation is not directly divided // instead, find a 52429/2^19 is about 0.1000... // It is equivalent to dividing i by 10, but what I don't know is why it is not directly// Divided by 10, maybe because the accuracy is insufficient, division produces a floating point Número, // Tal vez sea inexacto, y luego multiplique el divisor por 10 para obtener el número de más de 10 dígitos // Parte. Por i-el número con más de diez dígitos en esta parte, obtienes el número de dígitos individuales para (;;) {q = (i * 52429) >>> (16+3); r = i - ((q << 3) + (q << 1)); // r = i- (q*10) ... buf [--charpos] = dígitos [r]; i = Q; if (i == 0) romper; } if (signo! = 0) {buf [--charpos] = sign; }} final static int [] sizetable = {9, 99, 999, 9999, 999999, 999999, 999999, 999999, 9999999, 99999999, Integer.max_value}; // Esto debe optimizarse aquí, y los bits de los datos enteros se almacenan a través de Sizetable //, de uno a 10 bits: 2147483647, // Este método de procesamiento es inteligentemente estático int stringsize (int x) {para (int i = 0;; i ++) if (x <= Sizetable [i]) return I+1; }Interpretación del método Highestonebit
public static int highestonebit (int i) {// hd, figura 3-1 i | = (i >> 1); i | = (i >> 2); i | = (i >> 4); i | = (i >> 8); i | = (i >> 16); regresar i - (i >>> 1); }Este método es muy interesante. Lo calculé yo mismo antes de entender su esencia. La función de este método es encontrar el valor del entero representado por la parte más grande de un entero. Esta función se realiza aquí a través del desplazamiento. Demos un ejemplo simple. Para 128, el binario es 1000 0000. Tomemos como ejemplo:
Mover 1 dígito
1000 0000
0100 0000
| -------------
Mover 2 dígitos
1100 0000
0011 0000
| ------------
Mover 4 bits
1111 0000
0000 1111
| ------------
Mover 8 bits
1111 1111
0000 0000
| ------------
Móvil 16 bits
1111 1111
0000 0000
| ------------
1111 1111
El resultado final es como puedes ver. Todos los siguientes bits están llenos de 1, y todos los bits siguientes se restan para obtener el entero representado por el bit más alto.
Análisis de métodos de cuenta de bits
public static int bitCount (int i) {// hd, figura 5-2 i = i - ((i >>> 1) y 0x555555555); i = (i & 0x333333333) + ((i >>> 2) y 0x333333333); i = (i + (i >>> 4)) y 0x0f0f0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); regresar i & 0x3f; } Este método fue realmente inútil durante mucho tiempo para estudiar, y luego descubrí una idea aproximada:
En la primera línea, la implementación es agrupar los bits binarios del tipo entero en dos y dos, y luego contar el número de 1 entre los dos bits. No sé cómo proviene esta fórmula, pero de hecho es el caso.
La segunda línea implementa la agrupación de cuatro y cuatro bits binarios del entero, y luego calcula la adición de cambio dentro del segmento, que es 1001-> 10 + 01 = 11. Es equivalente a tres 1. La tercera línea es agrupar ocho bits binarios del entero, y luego agregar desplazamientos similares al método anterior. Por supuesto, esto se logra a través de algunos cambios y operaciones específicos.
Luego son dieciséis grupos y treinta y dos grupos, y finalmente fusionan las estadísticas en las estadísticas representadas por los últimos dígitos.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.