Riesgo de operaciones lógicas de variables de punto flotante en c ++

Errores de redondeo en el cálculo de coma flotante pueden crear estragos con las operaciones lógicas en C ++, por lo que debe tener cuidado de realizar operaciones lógicas de variables de punto flotante. Considere el siguiente ejemplo:

flotar f1 = 10.0-float f2 = f1 / 3-bool b1 = (f1 == (f2 * 3.0)) - // son estos dos iguales?

A pesar de que es obvio para nosotros que f1 es igual a f2 3 veces, el valor resultante de b1 no es necesariamente cierto. Una variable de punto flotante no puede contener un número ilimitado de dígitos significativos. Por lo tanto, f2 no es igual a la cantidad que llamaríamos " de tres y un tercio, " sino más bien a 3,3333 # 133-, deteniéndose después de algún número de decimales.

LA flotador variables soporta cerca de 7 dígitos de precisión, mientras que una doble apoya una skosh más de 16 dígitos. Estas cifras son aproximadas ya que el equipo es probable que genere un número como 3,3333347 debido a los caprichos de los cálculos de punto flotante.

Ahora, en pura matemática, el número de 3s después del punto decimal es infinito, pero ningún equipo construido puede manejar un número infinito de dígitos. Así que, después de multiplicar por 3,3333 3, se obtiene 9,9999 en lugar de los 10 que tendrías si multiplicado " de tres y un tercio " - En efecto, una error de redondeo. Tales diferencias pequeñas pueden ser imperceptible para una persona, pero no a la computadora. Igualdad significa exactamente eso - exacto la igualdad.

Los procesadores modernos son sofisticados en la realización de estos cálculos. El procesador puede, de hecho, acomodar el error de redondeo, pero desde el interior de C ++, no se puede predecir con exactitud lo que va a hacer cualquier procesador dado.

La comparación más seguro sigue:

flotar f1 = 10.0-float f2 = f1 / 3-float f3 = f2 * 3.0-float delta = f1 - f3-bool bEqual = -0.0001 lt; delta delta lt; 0.0001-

Esta comparación es cierto si f1 y f3 se encuentran dentro de un pequeño delta entre sí, que todavía debe ser cierto incluso si usted toma algún pequeño error de redondeo en cuenta.

La lógica AND y lógico OR || operadores en C ++ realizar lo que se llama evaluación de cortocircuito. Considera lo siguiente:

condición1 condition2

Si condición1 no es cierto, el resultado global no es cierto, no importa lo que el valor de condition2. (Por ejemplo, condition2 podría ser cierto o falso . sin cambiar el resultado) La misma situación se produce en el siguiente:

condición1 || condition2

Si condición1 es cierto, el resultado es cierto, no importa lo que el valor de condition2 es.

Para ahorrar tiempo, C ++ no evalúa condition2 si no es necesario. Por ejemplo, en la expresión condición1 condition2, C ++ no evalúa condition2 si condición1 es falsa. Del mismo modo, en la expresión condición1 || condition2, C ++ no evalúa condition2 si condición1 es cierto. Esto se conoce como evaluación de corto-circuito.

Evaluación de cortocircuito puede significar que condition2 no se evalúa incluso si esa condición tiene efectos secundarios. Considere el siguiente fragmento de código es cierto ideado:

int nArg1 = 1-int nArg2 = 2-int nArg3 = 3-bool b = (nArg1> nArg2) (nArg2 ++> nArg3) -

La variable nArg2 Nunca se incrementa porque la comparación nArg2 ++> nArg3 no se realiza. No hay necesidad, porque nArg1> nArg2 ya devuelto un falso por lo que la expresión general debe ser falsa.




» » » » Riesgo de operaciones lógicas de variables de punto flotante en c ++