Ver Mensaje Individual
  #15 (permalink)  
Antiguo 18/05/2016, 04:43
aguml
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 8 meses
Puntos: 3
Respuesta: Saber si un double se ha desbordado

pues puedo decir que me suena casi todo eso a chino pero he estado experimentando antes de tu respuesta y he visto cosas:
1- No sirve usar:
Código C:
Ver original
  1. double a,b;
  2.     b=a=DBL_MAX;
  3.     a++;
  4.     if(b > a)
  5.        printf("Huvo overflow");
es curioso pero en ese caso a y b valen igual incluso habiendo incrementado una de ellas.

2- No sirve el truco:
Código C:
Ver original
  1. double a=DBL_MAX;
  2.     a++;
  3.  
  4.     __asm{
  5.         pushad
  6.         pushfd
  7.         pop eax
  8.         mov flags, eax
  9.         popfd
  10.         popad
  11.     }
  12.     if(flags & (1<<11))
  13.         printf("Hubo overflow");
No se activa el flag de overflow.

3- Hice esto:
Código C:
Ver original
  1. double a=DBL_MAX;
  2.     a *=2;
Esto me suelta una excepcion diciendo que se ha desbordado. ¿se podria usar try catch para controlar si se produjo overflow en un double? ¿eso seria una locura?
Para controlar la entrada de scanf encontre una solucion mas o menos razonable:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. //#include <math.h>
  5.  
  6. #define BEEP 7
  7. #define MAX 20
  8. #define POS_INF 1.0 /0.0;
  9. #define NEG_INF -1.0/0.0;
  10.  
  11. double leer_double(void) {
  12.     double x;
  13.     char a[MAX], *p, c;
  14.    int i, encontrado = 0;
  15.  
  16.     fgets(a, MAX, stdin);
  17.     x = strtod (a, &p);
  18.  
  19.    if(errno == ERANGE){
  20.       printf("%s\n",strerror(errno)); //Huvo overflow
  21.       if(x==0){
  22.          x= NEG_INF;
  23.       }else{
  24.          x= POS_INF;
  25.       }
  26.    }else{
  27.       for(i = 0; i < MAX; i++){
  28.          if(a[i] == '\n'){
  29.             encontrado = 1;
  30.             break;
  31.          }
  32.       }
  33.  
  34.       if(*p != '\n'){
  35.          printf("%c",BEEP); /* Aviso de error */
  36.            printf("Dato incorrecto.\n");
  37.  
  38.          if(encontrado == 0){
  39.             do{ /* Ciclo para vaciar el resto que haya quedado en el buffer stdin */
  40.                  c = getchar();
  41.             }while(c != '\n');
  42.          }
  43.          x=0;
  44.        }
  45.    }
  46.     return x;
  47. }
  48.  
  49. int main() {
  50.     double d;
  51.  
  52.    printf("Introduce un valor: ");
  53.     d = leer_double();
  54.     printf ("retorno: %lf\n", d);
  55.     system("PAUSE");
  56.    return 0;
  57. }
¿que os parece esta solucion? ¿cambiariais algo?