Pregunta

Siempre he utilizado arroyos, printf, cadena (x) o cualquiera que sea el idioma en cuestión se ofreció para convertir tipos numéricos en una cadena o en la espalda. Sin embargo, nunca he considerado realmente cómo esto se hace realmente. Busqué en Google, pero todos los resultados son sólo para utilizar los métodos varía, y no cómo la conversión se hace realmente detrás de las escenas: (

Para enteros utilizando binario, octal y hexadecimal parece bastante sencillo ya que cada "dígitos" en la cadena representa un grupo conjunto de bits (por ejemplo, para los 2 dígitos hexadecimales que conozco su xxxxyyyy), por lo que podría hacerlo con desplazamientos de bit y teniendo un dígito a la vez, por ejemplo, para la cadena hexadecimal 0xFA20 el valor es "(15 << 12) | (10 << 8) | (2 << 4) | (0 << 0)".

enteros decimales son más difíciles desde la base 10 no se asigna a la base 2 de esa manera y así un bit puede afectar a más de un dígito decimal haciendo de conversión en ambos sentidos más complejo ...

En cuanto a los números de coma flotante que realmente no tienen idea. Creo que las partes enteras y fraccionarias podrían considerarse por separado o algo? ¿Qué hay de como una exponencial, un número determinado de cifras significativas o número determinado de decimales?

¿Fue útil?

Solución

conversiones

decimales son un poco más lento, pero no es realmente mucho más compleja. Echemos un vistazo a la conversión hexadecimal un poco más como nos gustaría probablemente escribir en código real. Sólo por ejemplo, en C ++ que podría hacer la conversión de algo como esto:

char digits[] = "0123456789abcdef";
std::string result;

int input = 0xFA20;

while (input) {
    int digit = input & 0xf; // or: digit = input % 0xf;
    input >>= 4;             // or: input /= 16;
    result.push_front(digits[digit]);
}

En este momento, sin embargo, que tiene unos números mágicos. Vamos a deshacernos de ellos:

const int base = 16;

while (input) { 
    int digit = input % (base - 1);
    input /= base;
    result.push_front(digits[digit]);
}

En el proceso de deshacerse de esos números mágicos, también hemos hecho la rutina casi universal - si cambiamos el valor de la 'base', el resto de la rutina sigue funcionando, y convierte la entrada a la especificada base. En esencia, el único otro cambio que necesitamos para hacer es añadir más a la matriz "dígitos" si queremos bases de apoyo de más de 16.

Esto también pasa por alto algunas cosas por razones de simplicidad. Lo más evidente, si el número es negativo, normalmente se establece una bandera, convertido a un número positivo, y al final, si se establece el indicador, pone un '-' en la cadena). Con el complemento a 2 hay un caso esquina para el número máximo negativo, que no se puede convertir en un número positivo (sin convertir a un tipo con más de alcance). Normalmente usted se ocupa de que mediante la promoción de la mayoría de los tipos. Para su tipo entero más grande (que no se puede promover) por lo general es más fácil de simplemente difícil que el código que un valor.

En principio coma flotante no es una porción entera diferente - que sigue siendo básicamente hacer manipulaciones matemáticas para generar un dígito a la vez. De hecho, se vuelve más compleja, simplemente porque normalmente se tiene que tratar con un par de diferentes formatos (por lo menos un punto flotante "básica" y algún tipo de formato "Ciencia"), así como las variables de la anchura del campo y precisión. En el momento en que haya tratado con eso, se termina con unos pocos cientos de líneas de código más o menos - la cantidad no es particularmente escandalosa, pero probablemente un poco más de sentido incluir aquí

.

Otros consejos

  

Busqué en Google, pero todos los resultados son sólo para utilizar los métodos varía, y no cómo la conversión se hace realmente detrás de las escenas: (

Por razones de rendimiento, la conversión de una representación a otra (conversiones particularmente de punto flotante / entero) es a menudo una instrucción de la CPU de bajo nivel y se implementa en el nivel de procesador. Es por eso que por lo general no se ve re-implementado en bibliotecas o en un nivel de idioma.

Esto es especialmente común en el mundo de procesamiento de señales, por ejemplo, cuando usted quiere tomar una forma de onda y convertirlo en un valor entero discreto en algún rango.

Para enteros se pueden encontrar resto de la división, este es el último dígito, se divide por 10, que se encuentra modular residual - este es uno, pero el último dígito, y así sucesivamente. números de coma flotante se construyen de dos partes - dígitos significativos y exponente, es decir, número = significant.digits * (base ^ exponente), donde la base puede ser de 10, 2, u otro número.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top