Herramientas de usuario

Herramientas del sitio


punto_flotante

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
punto_flotante [2020/03/25 03:44] – [Representación de Punto Flotante] charlypunto_flotante [2021/11/09 16:58] (actual) – editor externo 127.0.0.1
Línea 58: Línea 58:
 Notar que el número debe tener un solo dígito distinto de cero en la parte entera. Esto implica que el cero no es un número normalizado, sino que tiene una representación especial. Notar que el número debe tener un solo dígito distinto de cero en la parte entera. Esto implica que el cero no es un número normalizado, sino que tiene una representación especial.
  
-Por ejemplo el número no normalizado 101012 es igual al valor normalizado 1,0101 × 2<sup>4</sup>.+Por ejemplo el número no normalizado 10101 es igual al valor normalizado 1,0101 × 2<sup>4</sup>.
  
 Consideraremos mantisa solamente a los dígitos binarios de la parte fraccionaria del número normalizado, asumiendo que la parte entera siempre vale 1. Consideraremos mantisa solamente a los dígitos binarios de la parte fraccionaria del número normalizado, asumiendo que la parte entera siempre vale 1.
Línea 91: Línea 91:
  
 |signo (1 bit)|exponente (8 bits)|mantisa normalizada (23 bits)| |signo (1 bit)|exponente (8 bits)|mantisa normalizada (23 bits)|
 +
  
 Veamos cómo codificar un número cualquiera en Punto Flotante de precisión simple, por ejemplo: **534,5**. Veamos cómo codificar un número cualquiera en Punto Flotante de precisión simple, por ejemplo: **534,5**.
  
 +  - En primer lugar debemos expresarlo como un número binario normalizado. Aplicando divisiones sucesivas y multiplicaciones sucesivas por 2 obtenemos que 
 +534,5<sub>10</sub> = 1000010110,1<sub>2</sub>
 +  - Como la parte entera es mayor a 1, debemos normalizarlo. En este caso alcanza con dividirlo 9 veces por 2 para que solo quede un uno en la parte entera. Luego 534,510 = 1000010110,1<sub>2</sub> = 1,0000101101<sub>2</sub> × 2<sup>9</sup>. Notar que si efectuamos el producto obtendremos el número original.
 +  - Como el número es positivo, el bit de signo será s = 0.
 +  - Codificamos el exponente 9 en **exceso-127**: 9 + 127 = 136 = 10001000<sub>2</sub>
 +  - Finalmente en los 23 bits de la mantisa se almacenan los dígitos de la parte fraccionaria, completando con ceros a la derecha en caso de que sean menos de 23. La representación binaria en punto flotante de 32 bits quedará así:
 +
 +{{:pf.png?nolink&250|}}
 +
 +Dado que la representación de PF de 32 bits ocupa 4 bytes, es frecuente expresar el contenido de estos 4 bytes de manera más compacta en hexadecimal, de la misma manera que se visualiza el contenido de la memoria en hexadecimal.
 +
 +En este caso los bits
 +''0100 0100 0000 0101 1010 0000 0000 0000''
 +se pueden expresar en hexadecimal de la siguiente manera:
 +''44 05 A0 00''
 +
 +==== Decodificar un número de Punto Flotante de precisión simple ====
 +Suponiendo que obtenemos de la memoria 4 bytes que contienen un número real representado en punto flotante de precisión simple, podemos extraer el número que contiene siguiendo los pasos inversos.
 +
 +Si el contenido de estos cuatro bytes expresado en hexadecimal es
 +
 +''BE 40 00 00''
 +
 +Debemos pasarlo a binario para poder extraer el signo, el exponente y la mantisa:
 +
 +''1011 1110 0100 0000 0000 0000 0000 0000''
 +
 +  - Separando las partes quedará {{:pf2.png?nolink&300|}}\\ 
 +  - Como s=1, vemos que el número es **negativo**.\\ <color #ffffff>.</color>
 +  - Como el exponente está codificado en exceso 127, podemos restarle 127 para obtener el exponente real:\\ 
 +    - 01111100<sub>2</sub> = 64 + 32 + 16 + 8 + 4 = 124
 +    - e = 124 - 127 = **-3**\\ <color #ffffff>.</color>
 +  - Podemos expresar el número binario normalizado reemplazando cada una de las partes\\ 
 +    - f = (s) 1,m × 2<sup>e</sup> = -1,10000000000000000000000<sub>2</sub> × 2<sup>-3</sup> 
 +    - Desnormalizándolo queda: f = **-0,0011<sub>2</sub>**\\ <color #ffffff>.</color>
 +  - Finalmente el valor del número de punto flotante expresado en decimal será\\ f = -0,0011<sub>2</sub> = -(1/8 + 1/16) = -(0,125 + 0,0625) = **-0,1875<sub>10</sub>**
 +
 +==== Consideraciones sobre la operación con números de punto flotante ====
 +Al tratarse de una representación finita de un conjunto infinito, hay que tener en cuenta que tanto la representación de números como las operaciones de punto flotante involucran un error en la mayoría de los casos.
 +Esto puede provocar situaciones como la siguiente, por ejemplo en Python:
 +    >>> 0.1 + 0.1 + 0.1 == 0.3
 +    False
 +
 +{{youtube>W8GBE6sdVuQ?large}}
 +
 +Notar que la representación binaria de 0,1 requiere infinitos dígitos, por lo que el valor representado como ''0.1'' no es exactamente 0,1. Podemos ver la diferencia si mostramos el valor ''0.1'' con una cantidad grande de dígitos en la parte fraccionaria:
 +
 +    >>> '{0:.20g}'.format(0.1)
 +    '0.10000000000000000555'
 +
 +Esto sugiere que en muchos casos será un error comparar números de punto flotante usando la igualdad.
 +
 +Además del error involucrado en la representación, cada operación de punto flotante introduce un error que es inevitable. Hay situaciones donde el orden en que se realicen las operaciones puede amplificar o disminuir el error. Por ejemplo restar dos números muy parecidos puede cancelar dígitos significativos magnificando el error.
 +
 +
 +----
 +
 +{{youtube>eBkJilWMYvU?large}}
 +**Normalización  en decimal**
 +
 +----
 +
 +{{youtube>ijBLqXhq9RY?large}}
 +**Punto Flotante** 
 +
 +==== Referencias ====
 +  * Tanenbaum - Apéndice B
 +
 + --- //[[charlylh@gmail.com|Carlos López Holtmann]]//
 +
 +~~NOCACHE~~
 +({{counter|total}})
  
  
× iphelper toolbox

you see this when javscript or css is not working correct

Untested
IP Address:
First usable:
Subnet:
Last usable:
CIDR:
Amount of usable:
Network address:
Reverse address:
Broadcast address:

punto_flotante.1585107850.txt.gz · Última modificación: 2020/03/25 03:44 por charly