Cómo juzgar la validez de los números de punto flotante (lenguaje C)

1. Descripción del problema

  En el proceso de programación, a veces debido a una mala consideración o precisión del cálculo, el resultado del cálculo es "anormal": nan (No es un número) o inf (Infinito). Este artículo primero resume la situación que hace que el resultado del cálculo sea nan o inf durante el proceso de programación, y luego proporciona un método para juzgar la validez de los números de punto flotante.

1. ¿En qué circunstancias el resultado del cálculo es inf

  El resultado del cálculo es inf generalmente porque el resultado del cálculo excede el rango de números de coma flotante.
  Por ejemplo: float y [5] = {log (0.0), 1.0 / 1.0e-50, exp (1000.0), 2.0 * FLT_MAX, FLT_MAX * FLT_MAX};
  cuando el resultado del cálculo de la variable es inf, la variable se puede combinar con otros flotantes Los puntos se utilizan para operaciones de comparación u otras operaciones, al igual que el infinito en matemáticas.
  En el archivo de encabezado <flaot.h>, se define la constante DBL_MAX (FLT_MAX). Esta constante representa "el valor de punto flotante de precisión doble (simple) más grande que se puede representar". Utilice la función: int is_finite_number (doble x) {return (x> = -DBL_MAX && x <= DBL_MAX);} o int is_finite_number (float x) {return (x> = -FLT_MAX && x <= FLT_MAX);} para juzgar x ¿Es un número finito (ni inf ni nan)? Si x es inf, devuelve 0; de lo contrario, devuelve 1.

2. ¿En qué circunstancias el resultado del cálculo es nan

  El resultado del cálculo es nan generalmente debido a operaciones indefinidas en números de punto flotante.
  Por ejemplo: float y [5] = {sqrt (-1.0), acos (1.000006), asin (-1.001), pow (-1, 0.25), log (-1.0)};
  al mismo tiempo, 0.0 / 0.0, 0.0 * inf , Inf / inf, inf-inf operaciones también obtendrán nan.
  Se puede verificar Cuando se juzga nan == nan, el resultado es 0 o falso. Por lo tanto, puede usar la función: int is_number (double x) {return (x == x); para determinar si x es nan. Si x es nan, devuelve 0; de lo contrario, devuelve 1.

En segundo lugar, juzgue la validez de los números de punto flotante

  El archivo de encabezado <math.h> define la macro fpclassify (x) para ver la expresión numérica de punto flotante x. El valor de retorno tiene las siguientes cinco situaciones:
  (1) FP_NAN: x es un "no es un número";
  ( 2) FP_INFINITE: x es infinito positivo y negativo;
  (3) FP_ZERO: x es 0;
  (4) FP_SUBNORMAL: x es demasiado pequeño para expresarse en la forma normalizada de números de coma flotante;
  (5) FP_NORMAL: x es un valor normal Número de coma flotante (ninguno de los resultados anteriores).
  Al mismo tiempo, el lenguaje c proporciona cuatro macros para juzgar la validez de números de coma flotante:
  #define isfinite (_Val) (fpclassify (_Val) <= 0)
  #define isinf (_Val) (fpclassify (_Val) == FP_INFINITE)
  #define isnan (_Val) (fpclassify (_Val) == FP_NAN)
  #define isnormal (_Val) (fpclassify (_Val) == FP_NORMAL)

Tres, CCCódigo C

#include <stdio.h>
#include <math.h>
#include <float.h>

const char *show_classification(float x) 
{
    
    
	switch (fpclassify(x)) 
	{
    
    
		case FP_INFINITE:  
			return "Inf";
			break;
		case FP_NAN:       
			return "NaN";
			break;
		case FP_NORMAL:
			return "Normal";
			break;
		case FP_SUBNORMAL:
			return "Subnormal";
			break;
		case FP_ZERO:
			return "Zero";
			break;
		default:
			return "Unknown";
			break;
	}
}

void main(void)
{
    
    
	printf("log(0.0) is %s\n", show_classification(log(0.0)));
	printf("1.0 / 1.0e-50 is %s\n", show_classification(1.0 / 1.0e-50));
	printf("exp(1000.0) is %s\n", show_classification(exp(1000.0)));
	printf("2.0 * FLT_MAX is %s\n", show_classification(2.0 * FLT_MAX));
	printf("FLT_MAX * FLT_MAX is %s\n", show_classification(FLT_MAX * FLT_MAX));
	printf("\n");
	printf("sqrt(-1.0) is %s\n", show_classification(sqrt(-1.0)));
	printf("acos(1.000006) is %s\n", show_classification(acos(1.000006)));
	printf("asin(-1.001) is %s\n", show_classification(asin(-1.001)));
	printf("pow(-1, 0.25) is %s\n", show_classification(pow(-1, 0.25)));
	printf("log(-1.0) is %s\n", show_classification(log(-1.0)));
	printf("\n");

	printf("FLT_MIN/2 is %s\n", show_classification(FLT_MIN / 2.0));
	printf("-0.0 is %s\n", show_classification(-0.0));
	printf("1.0 is %s\n", show_classification(1.0));
}

Resultados de ejecución del programa

4. Referencias / Información

Cómo juzgar la validez de números de punto flotante en lenguaje C
fpclassify

Supongo que te gusta

Origin blog.csdn.net/maple_2014/article/details/104545713
Recomendado
Clasificación