El formato de punto flotante de precisión simple (a veces llamado FP32 o float32 ) es un formato de número de computadora , que generalmente ocupa 32 bits en la memoria de la computadora ; representa un amplio rango dinámico de valores numéricos mediante el uso de un punto de base flotante .
Una variable de punto flotante puede representar un rango más amplio de números que una variable de punto fijo del mismo ancho de bits a costa de la precisión. Una variable entera de 32 bits con signo tiene un valor máximo de 2 31 − 1 = 2.147.483.647, mientras que una variable de punto flotante de base 2 de 32 bits IEEE 754 tiene un valor máximo de (2 − 2 −23 ) × 2 127 ≈ 3,4028235 × 10 38 . Todos los números enteros con siete o menos dígitos decimales, y cualquier 2 n para un número entero −149 ≤ n ≤ 127, se pueden convertir exactamente en un valor de punto flotante de precisión simple IEEE 754.
En el estándar IEEE 754 , el formato base 2 de 32 bits se conoce oficialmente como binary32 ; en IEEE 754-1985 se lo llamó single . IEEE 754 especifica tipos de punto flotante adicionales, como la precisión doble base 2 de 64 bits y, más recientemente, las representaciones base 10.
Uno de los primeros lenguajes de programación que proporcionó tipos de datos de punto flotante de precisión simple y doble fue Fortran . Antes de la adopción generalizada de IEEE 754-1985, la representación y las propiedades de los tipos de datos de punto flotante dependían del fabricante y el modelo de la computadora, y de las decisiones tomadas por los diseñadores del lenguaje de programación. Por ejemplo, el tipo de datos de precisión simple de GW-BASIC era el formato de punto flotante MBF de 32 bits .
La precisión simple se denomina REAL en Fortran ; [1] SINGLE-FLOAT en Common Lisp ; [2] float en C , C++ , C# y Java ; [3] Float en Haskell [4] y Swift ; [5] y Single en Object Pascal ( Delphi ), Visual Basic y MATLAB . Sin embargo, float en Python , Ruby , PHP y OCaml y single en versiones de Octave anteriores a 3.2 se refieren a números de precisión doble . En la mayoría de las implementaciones de PostScript y algunos sistemas integrados , la única precisión admitida es single.
Formatos de punto flotante |
---|
IEEE 754 |
|
Otro |
Alternatives |
Tapered floating point |
El estándar IEEE 754 especifica que un binary32 tiene:
Esto proporciona una precisión de entre 6 y 9 dígitos decimales significativos . Si una cadena decimal con un máximo de 6 dígitos significativos se convierte al formato de precisión simple IEEE 754, lo que da como resultado un número normal , y luego se convierte nuevamente a una cadena decimal con el mismo número de dígitos, el resultado final debe coincidir con la cadena original. Si un número de precisión simple IEEE 754 se convierte a una cadena decimal con al menos 9 dígitos significativos y luego se convierte nuevamente a una representación de precisión simple, el resultado final debe coincidir con el número original. [6]
El bit de signo determina el signo del número, que es también el signo de la mantisa. El campo de exponente es un entero sin signo de 8 bits de 0 a 255, en forma sesgada : un valor de 127 representa el exponente real cero. Los exponentes van de −126 a +127 (es decir, de 1 a 254 en el campo de exponente), porque los valores de exponente sesgados 0 (todos 0) y 255 (todos 1) están reservados para números especiales ( números subnormales , ceros con signo , infinitos y NaN ).
El verdadero significado de los números normales incluye 23 bits fraccionarios a la derecha del punto binario y un bit inicial implícito (a la izquierda del punto binario) con valor 1. Los números subnormales y los ceros (que son los números de punto flotante más pequeños en magnitud que el número normal menos positivo) se representan con el valor de exponente sesgado 0, lo que le da al bit inicial implícito el valor 0. Por lo tanto, solo 23 bits fraccionarios del significado aparecen en el formato de memoria, pero la precisión total es de 24 bits (equivalente a log 10 (2 24 ) ≈ 7,225 dígitos decimales).
Los bits se distribuyen de la siguiente manera:
El valor real asumido por un dato binario de 32 bits dado con un signo dado , exponente sesgado e (el entero sin signo de 8 bits) y una fracción de 23 bits es
que produce
En este ejemplo:
de este modo:
Nota:
El exponente de punto flotante binario de precisión simple se codifica utilizando una representación binaria de desplazamiento , donde el desplazamiento cero es 127; también conocido como sesgo de exponente en el estándar IEEE 754.
Por lo tanto, para obtener el verdadero exponente tal como lo define la representación binaria de desplazamiento, el desplazamiento de 127 debe restarse del exponente almacenado.
Los exponentes almacenados 00 H y FF H se interpretan de manera especial.
Exponente | fracción = 0 | fracción ≠ 0 | Ecuación |
---|---|---|---|
00H = 00000000 2 | ±cero | número subnormal | |
01 H , ..., FE H = 00000001 2 , ..., 11111110 2 | valor normal | ||
FFH = 11111111 2 | ± infinito | NaN (silencio, señalización) |
El valor normal positivo mínimo es y el valor positivo mínimo (subnormal) es .
This section possibly contains original research. (February 2020) |
This section may be confusing or unclear to readers. In particular, the examples are simple particular cases (simple values exactly representable in binary, without an exponent part). This section is also probably off-topic: this is not an article about conversion, and conversion from decimal using decimal arithmetic (as opposed to conversion from a character string) is uncommon. (February 2020) |
En general, consulte el estándar IEEE 754 para la conversión estricta (incluido el comportamiento de redondeo) de un número real en su formato binario32 equivalente.
Aquí podemos mostrar cómo convertir un número real base 10 a un formato binario32 IEEE 754 utilizando el siguiente esquema:
Conversión de la parte fraccionaria: Considere 0,375, la parte fraccionaria de 12,375. Para convertirlo en una fracción binaria, multiplique la fracción por 2, tome la parte entera y repita con la nueva fracción por 2 hasta que se encuentre una fracción de cero o hasta que se alcance el límite de precisión que es de 23 dígitos fraccionarios para el formato IEEE 754 binary32.
Vemos que se puede representar exactamente en binario como . No todas las fracciones decimales se pueden representar en una fracción binaria de dígitos finitos. Por ejemplo, el decimal 0,1 no se puede representar en binario de forma exacta, solo aproximada. Por lo tanto:
Dado que el formato IEEE 754 binary32 requiere que los valores reales se representen en formato (ver Número normalizado , Número desnormalizado ), 1100.011 se desplaza a la derecha 3 dígitos para convertirse en
Finalmente podemos ver que:
De lo cual deducimos:
A partir de estos podemos formar la representación resultante en formato binario IEEE 754 de 32 bits de 12.375:
Nota: considere convertir 68.123 al formato IEEE 754 binary32: utilizando el procedimiento anterior espera obtener con los últimos 4 bits siendo 1001. Sin embargo, debido al comportamiento de redondeo predeterminado del formato IEEE 754, lo que obtiene es , cuyos últimos 4 bits son 1010.
Ejemplo 1: Consideremos el decimal 1. Podemos ver que:
De lo cual deducimos:
A partir de estos podemos formar la representación resultante en formato binario IEEE 754 de 32 bits del número real 1:
Ejemplo 2: Consideremos un valor de 0,25. Podemos ver que:
De lo cual deducimos:
A partir de estos podemos formar la representación resultante en formato binario IEEE 754 de 32 bits del número real 0,25:
Ejemplo 3: Consideremos un valor de 0,375. Vimos que
Por lo tanto, después de determinar una representación de 0,375, podemos proceder como se indica anteriormente:
A partir de estos podemos formar la representación resultante en formato binario IEEE 754 de 32 bits del número real 0,375:
This section possibly contains original research. (February 2020) |
This section may be confusing or unclear to readers. In particular, there is only a very simple example, without rounding. This section is also probably off-topic: this is not an article about conversion, and conversion to decimal, using decimal arithmetic, is uncommon. (February 2020) |
Si el valor binario32, 41C80000 en este ejemplo, está en hexadecimal, primero lo convertimos a binario:
Luego lo dividimos en tres partes: bit de signo, exponente y significando.
Luego agregamos el bit 24 implícito al significado:
y decodificamos el valor del exponente restando 127:
Cada uno de los 24 bits del significando (incluido el bit 24 implícito), del bit 23 al bit 0, representa un valor, comenzando en 1 y mitades para cada bit, de la siguiente manera:
bit 23 = 1bit 22 = 0,5bit 21 = 0,25bit 20 = 0,125bit 19 = 0,0625bit 18 = 0,03125bit 17 = 0,015625..bit 6 = 0,00000762939453125bit 5 = 0,000003814697265625bit 4 = 0,0000019073486328125bit 3 = 0,00000095367431640625bit 2 = 0,000000476837158203125bit 1 = 0,0000002384185791015625bit 0 = 0,00000011920928955078125
En este ejemplo, el significando tiene tres bits establecidos: bit 23, bit 22 y bit 19. Ahora podemos decodificar el significando sumando los valores representados por estos bits.
Luego necesitamos multiplicar por la base, 2, elevado al exponente, para obtener el resultado final:
De este modo
Esto es equivalente a:
donde s es el bit de signo, x es el exponente y m es el significando.
Estos ejemplos se dan en representación de bits , en hexadecimal y binario , del valor de punto flotante. Esto incluye el signo, el exponente (sesgado) y la mantisa.
0 00000000 00000000000000000000001 2 = 0000 0001 16 = 2 −126 × 2 −23 = 2 −149 ≈ 1.4012984643 × 10 −45 (número subnormal positivo más pequeño)
0 00000000 11111111111111111111111 2 = 007f ffff 16 = 2 −126 × (1 − 2 −23 ) ≈ 1,1754942107 ×10 −38 (número subnormal más grande)
0 00000001 00000000000000000000000 2 = 0080 0000 16 = 2 −126 ≈ 1,1754943508 × 10 −38 (número normal positivo más pequeño)
0 11111110 111111111111111111111111 2 = 7f7f ffff 16 = 2 127 × (2 − 2 −23 ) ≈ 3,4028234664 × 10 38 (número normal más grande)
0 01111110 11111111111111111111111 2 = 3f7f ffff 16 = 1 − 2 −24 ≈ 0,999999940395355225 (número mayor menor que uno)
0 01111111 000000000000000000000000 2 = 3f80 0000 16 = 1 (uno)
0 01111111 000000000000000000000001 2 = 3f80 0001 16 = 1 + 2 −23 ≈ 1.00000011920928955 (número más pequeño mayor que uno)
1 10000000 000000000000000000000000 2 = c000 0000 16 = −20 00000000 000000000000000000000000 2 = 0000 0000 16 = 01 00000000 000000000000000000000000 2 = 8000 0000 16 = −0 0 11111111 000000000000000000000000 2 = 7f80 0000 16 = infinito1 11111111 000000000000000000000000 2 = ff80 0000 16 = −infinito 0 10000000 10010010000111111011011 2 = 4049 0fdb 16 ≈ 3,14159274101257324 ≈ π ( pi )0 01111101 01010101010101010101011 2 = 3eaa aaab 16 ≈ 0.333333343267440796 ≈ 1/3 x 11111111 100000000000000000000001 2 = ffc0 0001 16 = qNaN (en procesadores x86 y ARM)x 11111111 000000000000000000000001 2 = ff80 0001 16 = sNaN (en procesadores x86 y ARM)
De manera predeterminada, 1/3 se redondea hacia arriba, en lugar de hacia abajo como la precisión doble , debido al número par de bits en la mantisa. Los bits de 1/3 más allá del punto de redondeo son 1010...
que es más de 1/2 de una unidad en el último lugar .
Las codificaciones de qNaN y sNaN no están especificadas en IEEE 754 y se implementan de manera diferente en distintos procesadores. Los procesadores de la familia x86 y de la familia ARM utilizan el bit más significativo del campo de significando para indicar un NaN silencioso . Los procesadores PA-RISC utilizan el bit para indicar un NaN de señalización .
El diseño del formato de punto flotante permite varias optimizaciones, que resultan de la fácil generación de una aproximación de logaritmo de base 2 a partir de una vista entera del patrón de bits sin procesar. La aritmética de enteros y el desplazamiento de bits pueden producir una aproximación a la raíz cuadrada recíproca ( raíz cuadrada inversa rápida ), que se requiere comúnmente en gráficos de computadora .