¿Cómo convierto un número real como 0.72 a un binario? ¿Por qué necesito seguir multiplicando el número por 2?

¿Cómo convierto un número real como 0.72 a un binario? ¿Por qué necesito seguir multiplicando el número por 2?

Para convertir un número de coma flotante, [math] x, [/ math] que está entre 0 y 1, a binario, el procedimiento construye una cadena de resultados de la siguiente manera: Primero, inicialice la cadena de resultados a “0”. Luego, siempre que [math] x [/ math] sea distinto de cero, realice un ciclo en el que verifique si [math] 2x \ ge 1, [/ math] y, si es así, agregue “1” al resultado, doble x, y resta 1. Por otro lado, si [matemática] 2x <1, [/ matemática] entonces agregue “0” al resultado, y doble x. Cada vez que dobla x, esencialmente cambia la representación interna de coma flotante de [math] x [/ math] un bit hacia la izquierda, con el bit más a la izquierda moviéndose al lugar “unos”. (El programa llama al número "número", pero lo he estado llamando "x" por simplicidad).

El programa que vinculó en su fuente de preguntas es defectuoso de varias maneras. El primer error que noté es que el programa omite la duplicación de [math] x [/ math] en el caso donde [math] 2x <1, [/ math] por lo que agregará un montón de ceros al resultado. Otro problema con el problema vinculado es que produce un ajuste sibilante cuando la cadena de resultados es más larga que 32 bits. La mayoría de las computadoras almacenan los llamados números de coma flotante de "doble precisión" que usan 64 bits, típicamente 53 bits para el "significado" con signo y 11 bits para el exponente con signo. [1] Entonces, al duplicar y restar 1 cuando sea necesario, se quedará sin dígitos almacenados después de hasta 53 iteraciones del bucle. Por lo tanto, el programa debe abstenerse de lanzar un ataque sibilante hasta que el tamaño del resultado esté más allá de la precisión de los números de coma flotante en su computadora. El último problema que noté con el programa es que produce un resultado incorrecto si la entrada es exactamente 1. La prueba inicial que verifica que el número es menor o igual a 1 debe cambiarse para garantizar que el número de entrada sea menor que 1. Además, la comprobación de errores inicial permite que el número de entrada sea exactamente 0. El resultado que se devuelve es "0", que es técnicamente correcto, pero no es habitual tener un punto decimal sin ningún dígito que lo siga. Un programa estéticamente más agradable devolvería "0" en lugar de "0".

También vale la pena señalar que el número real 0.72, o 18/25, no se puede almacenar exactamente en un número de punto flotante binario de 64 bits. Esto se debe a que 18/25 es un número binario repetitivo, que resulta ser [matemático] 0. \ overline {10111000010100011110}. [/ Matemático] Si realiza la lógica de su programa manualmente, verá que hay un bucle. Después de 20 iteraciones, obtienes el valor de 0,72 en x nuevamente. Pero en el mundo real, dado que el número no se había almacenado exactamente en el número de coma flotante original, obtienes 0.719999999972 en x después de 20 iteraciones. De hecho, en cada iteración del programa, todo el número de coma flotante se desplaza un bit hacia la izquierda y se agrega un cero al lado derecho. Entonces, después de 54 iteraciones en el mundo real, el programa necesariamente terminará.

Para darle una idea de por qué 18/25 es una fracción repetitiva en binario, dibujaré un paralelo con 1/7 en decimal. Así como el denominador de 1/7, 7, no es un factor de ninguna potencia de la base, 10, el denominador de 18/25, 25, no es un factor de ninguna potencia de la base, 2. Pero en la base 10 , resulta que 1/7 es igual a 142857/999999. Entonces 1/7 también es igual a 1428571428157/999999999999, etc. De manera similar, en la base 2, 18/25 es igual a 754974 / (2 ^ 20–1), que puede no parecer muy interesante, pero en binario, esto es 10111000010100011110 / 11111111111111111111. Entonces, ves, 18/25 es un binario repetitivo, al igual que 1/7 es un decimal repetitivo.

Dicho todo esto, su pregunta es sobre cómo debería funcionar el programa, por lo que responderé su pregunta con ese objetivo en mente. Si el programa funcionara correctamente, dada la representación necesariamente inexacta de 0.72 en binario, entonces funcionaría así, comenzando con 0.72.

[matemáticas] x [/ matemáticas] es 0.72. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.44. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.88. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.76. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.52. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.04. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.08. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.16. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0,32. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.64. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.28. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.56. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.12. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.24. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.48. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.959999999999. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.919999999998. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.839999999997. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.679999999993. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.359999999986. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.719999999972. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.439999999944. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.879999999888. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.759999999776. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.519999999553. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.039999999106. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.079999998212. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.159999996424. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.319999992847. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.639999985695. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.27999997139. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.55999994278. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.119999885559. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.239999771118. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.479999542236. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.959999084473. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.919998168945. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0.839996337891. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.679992675781. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.359985351563. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.719970703125. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.43994140625. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.8798828125. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.759765625. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.51953125. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.0390625. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.078125. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.15625. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.3125. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemática] x [/ matemática] es 0.625. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemática] x [/ matemática] es 0.25. [matemática] 2x <1, [/ matemática] por lo tanto agregue "0" a la cadena de resultados y establezca [matemática] x = 2x. [/ matemática]

[matemáticas] x [/ matemáticas] es 0.5. [math] 2x \ ge 1, [/ math] entonces agregue “1” a la cadena de resultados y establezca [math] x = 2x-1. [/ math]

[matemáticas] x [/ matemáticas] es 0. El resultado final es 0.1011100001010001111010111000010100011110101110000101.

Ediciones y Agradecimientos

Gracias a Peter Pangritz por llamar la atención sobre la diferencia entre la representación de 0.72 como un número binario repetitivo y la realización por computadora de ese número binario. Actualicé la respuesta para explicar cómo funciona esto.

Notas al pie

[1] Aritmética de punto flotante – Wikipedia

Multiplicar por 2 es un desplazamiento a la izquierda de la representación binaria del número. Por ejemplo, si la representación binaria es [matemática] 0.101_2 = 1/2 + 1/8 = 5/8 = 0.625_ {10} [/ matemática] y multiplica este número por 2 obtienes [matemática] 1.01_2 = 1 + 1/4 = 1.25_ {10} [/ matemáticas] y así sucesivamente. Entonces, un algoritmo para convertir un número como [math] 0.72_ {10} [/ math] a su representación binaria es

A) multiplique por 2. El dígito que aparece a la izquierda del punto es el siguiente bit.

B) Chop de este dígito.

C) Si el número resultante es desigual a cero, vaya al paso A.

Entonces, por ejemplo, con el número [math] 0.72_ {10} [/ math] obtienes

A) [matemáticas] 2 \ veces 0.72 = 1.44 [/ matemáticas]

B) Corta el [math] 1 [/ math] para obtener 0.44. [matemática] 1 [/ matemática] es el primer bit a la derecha del punto.

A) [matemáticas] 2 \ veces 0.44 = 0.88 [/ matemáticas]

B) Cortar [matemática] 0 [/ matemática] sale nuevamente [matemática] 0 [/ matemática], conduce a [matemática] 0.88 [/ matemática]. [matemática] 0 [/ matemática] es el segundo bit a la derecha del punto.

A) [matemáticas] 2 \ veces 0.88 = 1.76 [/ matemáticas]

B) Corta [matemática] 1 [/ matemática] para obtener [matemática] 0,76 [/ matemática]. [matemáticas] 1 [/ matemáticas] es el tercer bit a la derecha del punto.

Repita este procedimiento indefinidamente O hasta obtener cero en el paso B. La representación binaria de [math] 0.72_ {10} [/ math] comienza con [math] 0.101110000101 \ cdots_2 [/ math]. Puedes comprobar

[matemáticas] 1/2 + 1/8 + 1/16 + 1/32 + 1/1024 + 1/4096 \ aproximadamente 0.719970703125 [/ matemáticas]

La representación binaria del número [matemática] 0.72 [/ matemática] es periódica con el período [matemática] 10111000010100011110 [/ matemática] y la duración del periodo [matemática] 20 [/ matemática].

Digamos que 0.72 cuando se convierte a binario me dará 0.abcde.

Cuando multiplico 0.abcde por 2 obtengo a.bcde (porque multiplicar por 2 es equivalente al desplazamiento a la izquierda por 1 bit). Quitar parte integral de a.bcde me da ‘a’ como dígito binario. El 0.bcde residual se puede multiplicar por 2 para obtener ‘b’ y así sucesivamente.

Por lo tanto, para obtener el bit integral de un número, es necesario multiplicarlo por 2 y extraer parte integral del resultado. El residual (sin parte integral) se puede utilizar para obtener el siguiente bit y así sucesivamente.

Siguiendo el procedimiento descrito anteriormente, por las razones indicadas anteriormente, obtenemos 0.1011100001 .. como equivalente binario de 0.72.

Espero eso ayude.

More Interesting