(Completado) Tutorial para entender los errores de punto flotante de IEEE

Seleccione idioma Seleccione idioma
Id. de artículo: 42980 - Ver los productos a los que se aplica este artículo
Expandir todo | Contraer todo

En esta página

Resumen

Matemáticas de punto flotante es un tema complejo que confunde muchos programadores. El tutorial siguiente debería ayudarle a reconocer situaciones de programación que suelen probable que se producen errores de punto flotante y cómo evitarlos. Debe también permiten reconocer casos causadas por limitaciones de inherente matemáticas de punto flotante como frente a errores de compilador real.

Más información

Decimal y sistemas de número binario

Normalmente, nos cuenta cosas en base 10. La base es completamente arbitraria. La única razón que personas han utilizado tradicionalmente en base 10 es que tienen los 10 dedos, que han realizado útiles herramientas de recuento.

El número 532.25 en decimal (base 10) significa lo siguiente:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
       500    +     30     +      2     +     2/10    +    5/100
   _________
   =  532.25
				

En el sistema de número binario (base 2), cada columna representa una potencia de 2 en lugar de 10. Por ejemplo, el número 101.01 significa lo siguiente:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
       4     +      0    +     1     +      0     +    1/4
   _________
   =  5.25  Decimal
				

Cómo se representan enteros en los equipos

Puesto que no hay parte fraccionaria en un entero, su representación de equipo es mucho más sencillo que para los valores de punto flotante. Enteros normales en equipos personales (PC) son 2 bytes (16 bits) long con el bit más significativo que indica el signo. Enteros largos son 4 bytes. Los valores son números binarios sencillos positivo. Por ejemplo:
    1 Decimal = 1 Binary
    2 Decimal = 10 Binary
   22 Decimal = 10110 Binary, etc.
				

Sin embargo, enteros negativos se representan mediante combinación de complemento de dos. Para obtener el representación complementaria de dos para un número negativo, tomar la representación binaria para el valor de absoluto del número y voltear todos los bits y agregar 1. Por ejemplo:
   4 Decimal = 0000 0000 0000 0100
               1111 1111 1111 1011     Flip the Bits
   -4        = 1111 1111 1111 1100     Add 1
				

Tenga en cuenta que-1 decimal = 1111 1111 1111 1111 en binario, que explica por qué Basic considera-1 lógico true (todos los bits = 1). Esto es una consecuencia de no tener operadores distintos para las comparaciones lógicas y bit a bit. A menudo en Basic, es conveniente utilizar el fragmento de código siguiente cuando el programa va a realizar muchas comparaciones lógicas. Esto ayuda mucho legibilidad.
   CONST TRUE = -1
   CONST FALSE = NOT TRUE
				

Observe que agregar cualquier combinación de dos complementar números juntos mediante normal aritmética binaria produce el resultado correcto.

Complicaciones de punto flotante

Se puede representar exactamente cada entero decimal mediante un entero binario; sin embargo, esto no es true para que los números fraccionarios. De hecho, cada número de irrational en base 10 también será irrational en cualquier sistema con una base de menor que 10.

Binario, en particular, los números fraccionarios sólo que pueden representarse en el formulario p y q, donde q es una potencia entera de 2, se pueden expresar exactamente, con un número finito de bits.

Fracciones decimales incluso comunes, como el 0.0001 decimal, no se puede representar exactamente en binario. (0.0001 es una fracción binaria extensible con un período de 104 bits!)

Esto explica por qué un ejemplo sencillo, como la siguiente
   SUM = 0
   FOR I% = 1 TO 10000
      SUM = SUM + 0.0001
   NEXT I%
   PRINT SUM                   ' Theoretically = 1.0.
				

IMPRIMIR 1.000054 como mostrará. El pequeño error representar 0.0001 en binario se propaga a la suma.

Por el mismo motivo, siempre debe mucho cuidado cuando realiza las comparaciones en números reales. En el ejemplo siguiente se muestra un error de programación común:
   item1# = 69.82#
   item2# = 69.20# + 0.62#
   IF item1# = item2# then print "Equality!"
				

Esto no PRINT "Igualdad!" como 69.82 se no se puede representar exactamente en binario, lo que hace que el valor que el resultado de la asignación a ser LIGERAMENTE distintos (en binario) que el valor generado a partir de la expresión. En la práctica, deberá codificar siempre estas comparaciones de manera como para permitir algunos tolerancia. Por ejemplo:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"
				

Esto PRINT "Igual".

Números de formato de IEEE

QuickBasic para MS-DOS, versión 3.0 se suministró con una versión MBF (punto de flotante binario de Microsoft) y una versión de IEEE (Institute of Electrical y Electronics Engineers) para equipos con un coprocesador matemático. QuickBasic para MS-DOS, las versiones 4.0 y posteriores sólo utilizan IEEE. Microsoft decidió el estándar IEEE para representar valores de punto flotante en las versiones actuales de Basic para las siguientes tres razones principales:
  1. Para permitir que Basic para utilizar los coprocesadores matemáticos de Intel, qué formato utilizar IEEE. Coprocesadores de 80 x 87 serie Intel no pueden trabajar con números de formato binario de Microsoft.
  2. Para realizar interlanguage llamada entre Basic, C, Pascal, FORTRAN y MASM mucho más fácil. En caso contrario, las rutinas de conversión tendría que utilizarse para enviar los valores numéricos de un idioma a otro.
  3. Para conseguir coherencia. IEEE es el aceptado estándar del sector para compiladores de C y FORTRAN.
Ésta es una comparación rápida de IEEE y MBF representaciones para un número de precisión doble:
               Sign Bits   Exponent Bits   Mantissa Bits
               ---------   -------------   -------------
   IEEE        1           11              52 + 1 (Implied)
    MBF        1            8              56
				

Para obtener más información sobre las diferencias entre IEEE y MBF representación de punto flotante, consulta en Microsoft Knowledge Base en las siguientes palabras:
   IEEE and floating and point and appnote
				

Tenga en cuenta que IEEE tiene más bits dedicados a exponente, que permite que represente una amplia gama de valores. MBF tiene más bits de mantisa, que le permite ser más precisos al intervalo más estrecho.

Conceptos generales de punto flotante

Es muy importante tener en cuenta que cualquier sistema de punto flotante binario puede representar sólo un número finito de valores de punto flotante de forma exacta. Todos los demás valores se deben aproximados por el valor representable más cercano. El estándar IEEE especifica el método para redondear los valores para el valor representable "más próximo". QuickBasic para MS-DOS admite el estándar y redondea conforme a las reglas IEEE.

Además, tenga en cuenta que los números que pueden representarse en IEEE se propagan sobre un rango muy ancha. Se puede considerar en una línea de número. Hay una alta densidad de se puede representables números cerca 1.0 y-1.0 pero menos y menos que vaya hacia 0 o infinito.

El objetivo del estándar IEEE, que está diseñado para los cálculos de ingeniería es maximizar la precisión (para obtener número cerca posible a la actual). Precisión se refiere al número de dígitos que puede representar. El estándar IEEE intenta equilibrar el número de bits dedicados para el exponente con el número de bits utilizados para la parte fraccionaria de número, para mantener la precisión y la precisión dentro de límites aceptables.

Detalles de IEEE

Números de punto flotante se representan en el formulario siguiente, donde [exponente] es el exponente binario:
   X =  Fraction * 2^(exponent - bias)
				

[Fracción] es la normalizado fraccionaria parte el número normalizado porque el exponente se ajusta para que el bit inicial sea siempre un 1. De este modo, no es necesario que se va a almacenar y obtendrá un poco más de precisión. Ésta es la razón por hay un bit implícito. Puede considerar esto como notación científica, donde se manipula el exponente para tener un dígito a la izquierda del separador decimal, excepto en binario, siempre manipulan al exponente para que el primer bit es 1, puesto que hay sólo unos y ceros.

[diferencia] es el valor diferencia que se utiliza para evitar tener que almacenar a los exponentes negativos.

La diferencia para números de precisión simple es 127 y 1023 (decimal) para números de precisión doble.

Los valores de igual a 0 todos y todos los 1 (binario) están reservados para que representa a casos especiales. Hay otros casos especiales, que indican diversas condiciones de error.

Ejemplos de precisión simple

2 = 1 * 2 ^ 1 = 0100 0000 0000 0000... 0000 0000 = 4000 0000 hex
Nota el bit de signo es cero y el exponente almacenado es 128, o 100 0000 0 en binario, que es 127 más 1. La mantisa almacenada es (1). 000 punto de 0000 0000, que tiene un líder implícita 1 y binario de 0000..., por lo que el valor real de la mantisa es 1.

-2 =-1 * 2 ^ 1 = 1100 0000 0000 0000... 0000 0000 = C000 0000 hex
Igual que + 2, excepto que el bit de signo está establecido. Esto es cierto para todos los números de punto flotante formato de IEEE.

4 = 1 * 2 ^ 2 = 0000 0100 1000 0000... 0000 0000 = hex 4080 0000
Misma mantisa, exponente aumenta en uno (el valor sesgado es 129, o 100 0000 1 en binario.

6 = 1.5 * 2 ^ 2 = 0000 0100 1100 0000... 0000 0000 = 40 C 0 hex 0000
Mismo exponente, mantisa es mayor por la mitad: es (1,) 100 0000... 0000 0000, que, puesto que esto es una fracción binaria, es 1-1 de 2 (los valores de los dígitos fraccionarios son 1/2, 1/4, 1/8, etc..).

1 = 1 * 2 ^ 0 = 1111 0011 1000 0000... 0000 0000 = 3F80 0000 hex
Mismo exponente que otras potencias de 2, mantisa es uno menor que 2 al 127 o 011 1111 1 en binario.

1.5 * 0,75 = 2 ^-1 = 0011 1111 0100 0000... 0000 0000 = 3F40 0000 hex
El exponente sesgado es 126, 011 1111 0 en binario y la mantisa es (1,) 100 0000... 0000 0000, que es 1-1 de 2.

2.5 = 1,25 * 2 ^ 1 = 0100 0000 0010 0000... 0000 0000 = hex 4020 0000
Exactamente el mismo que 2, excepto que el bit que representa 1/4 está establecido en la mantisa.

1.6 = 0,1 * 2 ^-4 = 0011 1101 1100 1100... 1100 1101 = 3DCC CCCD hex
1/10 es una fracción extensible en binario. La mantisa es simplemente tímida de 1,6, y el exponente sesgado indica que 1,6 dividirse por 16 (es 011 1101 1 en binario, que es 123 en decimal). El exponente real es 123-127 = - 4, que significa que el factor por el que se debe multiplicar es 2 **-4 = 1/16. Tenga en cuenta que la mantisa almacenada se redondea hacia arriba en el último bit. Esto es un intento para representar el número unrepresentable precisa posible. (La razón que 1/10 y 1/100 son representables no exactamente en binario es similar a la manera en que 1/3 es representable no exactamente en decimal.)

0 = 1.0 * 2 ^-128 = todo ceros--un caso especial.

Otros errores comunes de punto flotante

Errores comunes de punto flotante son:
  1. Error de redondeo

    Este error se produce cuando todos los bits en un número binario no utilizadas en un cálculo.

    Ejemplo: Agregar 0.0001 a 0.9900 (precisión simple)

    0.0001 Decimal se representarán como:
    10100011011011100010111 (1) * 2^(-14+Bias) (13 inicial ceros en binario)
    0.9900 se representarán como:
    11111010111000010100011 (1) * 2^(-1+Bias)
    Ahora para agregar realmente estos números, se deben alinear los puntos decimales (binarios). Para ello debe estar Unnormalized. Aquí es la adición resultante:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
          +.111111010111000010100011 * 2^0
          ________________________________
           .111111010111011100110000 * 2^0
    
    						
    se le llama un error de redondeo porque algunos equipos redondean al desplazamiento de adición. Otras simplemente truncan. Redondear - desactivar errores son importantes a tener en cuenta siempre que está agregando o multiplicar dos valores muy diferentes.
  2. Restar dos casi iguales valores
           .1235
          -.1234
           _____
           .0001
    
    						
    Esto se puede normalizar. Tenga en cuenta que aunque los números de originales tuvieran cuatro dígitos significativos, el resultado sólo un dígito significativo.
  3. Desbordamiento y subdesbordamiento

    Esto ocurre cuando el resultado es demasiado grande o demasiado pequeño para ser representado por el tipo de datos.
  4. Error quantizing

    Esto ocurre con los números que no puedan representarse de forma exacta con el estándar de punto flotante.
  5. División por un número muy pequeño

    Esto puede desencadenar un error "división por cero" o se puede producir resultados incorrectos, como en el siguiente ejemplo:
          A = 112000000
          B = 100000
          C = 0.0009
          X = A - B / C
    
    						
    en QuickBasic para MS-DOS X ahora tiene el valor 888887, en lugar de la respuesta correcta, 900000.
  6. Error de salida

    Este tipo de error se produce cuando las funciones de salida modifican los valores que está trabajando.

Propiedades

Id. de artículo: 42980 - Última revisión: martes, 16 de agosto de 2005 - Versión: 3.1
La información de este artículo se refiere a:
  • Microsoft Visual Basic 2.0 Standard Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 1.0 Standard Edition
  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic for MS-DOS
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 para MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft Cinemania 97 Standard Edition
Palabras clave: 
kbmt KB42980 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 42980
Renuncia a responsabilidad de los contenidos de la KB sobre productos a los que ya no se ofrece asistencia alguna
El presente artículo se escribió para productos para los que Microsoft ya no ofrece soporte técnico. Por tanto, el presente artículo se ofrece "tal cual" y no será actualizado.

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com