Hola amigos estoy trabajando con un pequeñísimo proyecto de C que trabaja con fuerza bruta y doubles y quería saber como detectar si se ha desbordado al incrementarlo o al introducir un valor con scanf. ¿pueden ayudarme?
Gracias de antemano.
| |||
Saber si un double se ha desbordado Hola amigos estoy trabajando con un pequeñísimo proyecto de C que trabaja con fuerza bruta y doubles y quería saber como detectar si se ha desbordado al incrementarlo o al introducir un valor con scanf. ¿pueden ayudarme? Gracias de antemano. |
| ||||
Respuesta: Saber si un double se ha desbordado
Código C++:
Ver original Última edición por leosansan; 16/05/2016 a las 02:06 |
| |||
Respuesta: Saber si un double se ha desbordado No entiendo exactamente lo que haces ¿le restas el incremento para ver si desborda? Otra cosa es como saber si el valor añadido con scanf lo desborda. |
| |||
Respuesta: Saber si un double se ha desbordado Lo único que se me ocurre es usar float.h y obtener el valor máximo de un float y luego con scanf capturar una cadena y contar los caracteres de la parte entera y los de la parte decimal. Sabiendo el máximo de caracteres de la parte entera comparo ambas cadenas para ver si la que introduje es más grande y si no lo es sigo. Luego empiezo a comparar de izquierda a derecha si tiene el mismo número de caracteres enteros mirando que no sea mayor que el máximo permitido y si es menor no desborda y uso atolf o sscanf para convertir la cadena. Esa es mi idea pero no se cual es el valor máximo de un double porque como se muestra con notación científica... |
| ||||
Respuesta: Saber si un double se ha desbordado |
| |||
Respuesta: Saber si un double se ha desbordado Si pero eso me lo imprime con notación científica y no se si el número de dígitos de la parte entera tiene un máximo fijo o puede usar dijimos de la parte decimal. Tampoco se si hay una parte de memoria fija para decimales y otra para la entera. No se si me explico. Última edición por aguml; 16/05/2016 a las 14:00 |
| |||
Respuesta: Saber si un double se ha desbordado ¿Has probado a usar las utilidades de fenv.h? Esta librería permite leer los flags aritméticos y te puede servir para detectar ciertos problemas al operar con números, como desbordamiento, división por cero, ...
__________________ La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo. |
| |||
Respuesta: Saber si un double se ha desbordado El problema, como ya me explicaron aquí en otra ocasión, el Flag O se activa al haber overflow pero cuando llamo a scanf la última instrucción no va a producir overflow así que después del scanf no me va a servir de nada comprobar los Flags. atolf en caso de overflow no está definido su comportamiento con lo que no sirve. sscanf no se que pasará si se produce overflow. |
| ||||
Respuesta: Saber si un double se ha desbordado Como ya te ha dicho eferion lo primero que deberías de hacer es probar con <fenv.h>. El Flag obtenido por las funciones de <fenv.h> NO es un flag de la ALU. No obstante, no todos los compiladores dan soporte a ello en C. Puedes comprobar rápidamente si eso es una posibilidad linkando con -lm y mostrando todos los warnings (-Wall) y escribiendo el siguiente pragma
Código C:
Ver original Si te dice que el pragma no es conocido sólo se me ocurre una idea que no es portable de compilador a compilador. Si el comportamiento por defecto de tu compilador es redondear con roundToEven o roundToNearest el overflow quedará siempre con el valor a infinitivo si es overflow por encima para positivos o -infinitivo si overflow para negativos utilizando la función isinf de math.h |
| |||
Respuesta: Saber si un double se ha desbordado Tienes que comprender también que la librería estándar de C/C++ aún tiene muchas carencias y es algo a solucionar a medio/largo plazo. Una prueba de lo que digo es que es imposible hacer una aplicación completa únicamente con la STL... vale, si, se puede hacer si reinventas la rueda y reescribes cosas que ya están hechas en librerías no estándar como BOOST. Este contratiempo es un problema heredado de la época en la que vió la luz el lenguaje. Otros ejemplos los tienes en el soporte nulo (hasta C++17) de una librería estándar de sockets, la carencia total de librerías para leer XML, interfaz gráfica, gestión de la consola... (ojo, hablo de la STL, no de librerías de 3os o de soluciones caseras para suplir estas carencias) Así que toca hacerse a la idea de que las librerías actuales tienen ciertas limitaciones. Otra posibilidad es leer el dato como un string y comprobar (por ejemplo con expresiones regulares) que el valor va a estar dentro del rango posible de valores para el tipo elegido... o currarte un tipo propio con más precisión.
__________________ La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo. |
| |||
Respuesta: Saber si un double se ha desbordado Eso último es lo que deseo hacer pero no tengo claro a que se refiere el valor máximo de double. Por ejemplo si fuese 2.3456E+10 entiendo que es máximo es 23456000000 pero ¿que pasa con la parte decimal? O sea, si pongo 2345.99999999999999999999999 ¿que pasaría en este supuesto casi? Como ves seria menor que el máximo pero no se si se puede desbordar con la parte decimal ni la precisión de esta. |
| |||
Respuesta: Saber si un double se ha desbordado Cita: Para entender esa parte tienes que saber cómo se almacenan los números decimales en el sistema... ¿has mirado algo sobre ese tema?
Iniciado por aguml Eso último es lo que deseo hacer pero no tengo claro a que se refiere el valor máximo de double. Por ejemplo si fuese 2.3456E+10 entiendo que es máximo es 23456000000 pero ¿que pasa con la parte decimal? O sea, si pongo 2345.99999999999999999999999 ¿que pasaría en este supuesto casi? Como ves seria menor que el máximo pero no se si se puede desbordar con la parte decimal ni la precisión de esta.
Si los conceptos anteriores te suenan a chino entonces deberías darle un repaso a cómo se almacenan los números decimales en el sistema... es la base para entender cómo funcionan :) Un saludo.
__________________ La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo. |
| |||
Respuesta: Saber si un double se ha desbordado En doble precisión (64 bits) tendrás 15-16 dígitos de precisión. Si quieres imprimir más, te imprimirá ceros. Si tienes un desbordamiento, lo que ocurra depende del comilador. Por ejemplo, con Mingw 4.8.1 32 bits, me he encontrado con: 1. Si el desbordamiento es comno consecuencia de cálculos, o haciendo atof() a una cadena de caracteres que se corresponda con un número superior a DBL_MAX, te va a dar un resultado de INF (infinito). El programa no te dará error. 2. Si el desbordamiento es consecuencia de hacer un scanf() para un double e introduces un valor superior a DBL_MAX, el resultado será NaN (Not a Number). Los valores INF y NaN son combinaciones especiales de bits para un número en coma flotante. Si quieres detalles, mírate la norma IEEE 754. Si quieres evitar el desbordamiento, comprueba si tienes el tipo long double. Este es un tipo de 80 bits que utiliza el coprocesador de manera interna. Ojo, porque algunos compiladores te aceptarán long double como sinónimo de double. Utiliza sizeof, deberá darte 12 ó 16 bytes, dependiendo de si es un sistema de 32 ó de 64 bits, respectivamente. El rango de long double es de 1.xxxE+4932, con unos 20 dígitos de precisión. |
| |||
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:
es curioso pero en ese caso a y b valen igual incluso habiendo incrementado una de ellas.Ver original 2- No sirve el truco:
Código C:
No se activa el flag de overflow.Ver original 3- Hice esto:
Código C:
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?Ver original Para controlar la entrada de scanf encontre una solucion mas o menos razonable:
Código C:
¿que os parece esta solucion? ¿cambiariais algo? Ver original |
| |||
Respuesta: Saber si un double se ha desbordado Pues ya tienes deberes antes de seguir investigando... si no entiendes lo que estás manejando no vas a conseguir que funcione. Cita: double tiene una precisión determinada, como te ha comentado Fw190. Si tu tienes 1e80 y programas un bucle para que durante 10 años le sume valores de 1 en 1, el resultado final será 1e80 porque la unidad que sumas es tan sumamente pequeña en comparación con el número actual que su valor queda descartado... para entender el por qué es mejor que te documentes un poco ántes.La misma explicación que en el caso anterior. Esa suma no ha modificado el valor de la variable. Que te salte una excepción sí es algo característico de tu compilador o de las opciones de compilación... no deberías relajarte y pensar que con un try-catch ya lo tienes todo solucionado.
__________________ La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo. |
| |||
Respuesta: Saber si un double se ha desbordado Prueba
Código C:
Ver original |
| |||
Respuesta: Saber si un double se ha desbordado Bueno pues me tocara leer sobre el tema. ¿sabes de algún escrito o algo donde se trate el tema? Sobre el último código la verdad es que no se muy bien que hace pero tendría que ser algo más complejo ya que se harían sumas, restas, multiplicaciones, divisiones, raíces cuadradas, y potencias. |
| |||
Respuesta: Saber si un double se ha desbordado Lo que hace es comprobar antes de sumar (o de la resta) si va a provocar overflow o no. Te faltarían las pruebas para las otras operaciones. Si te vale el C++, este es un buen lugar para empezar http://en.cppreference.com/w/cpp/language/types |
| |||
Respuesta: Saber si un double se ha desbordado Si se trata de un algoritmo de fuerza bruta, no creo que sea conveniente hacer comprobaciones de cada operando antes de operar para ver si va a haber overflow, te podrías eternizar. Si crees que puedes tener overflow de un double, como ya te comenté, prueba a ver si dispones del tipo long double. Otras opciones podrían ser: En ocasiones, el cambiar el orden de las operaciones puede obrar maravillas. Utiliza una librería de precisión arbitraria. No indicas qué compilador utilizas, para el compilador GNU tienes la GMP, y buscando podrás encontrar otras. Algunos compiladores disponen de un tipo qfloat de 384 bits (no, no es un error). Esto te daría unos 100 dígitos de precisión. No recuerdo en este momento el rango, pero creo que es superior al de long double. Con este tipo tienes, por ejemplo, el compilador Lcc-Win32 (creo que hay también una versión para 64 bits). |
| |||
Respuesta: Saber si un double se ha desbordado Realmente no creo que con las operaciones que realizo se desbordaría pero era por informarme para cuando lo necesitara. Muchas gracias a todos por la info. |
Etiquetas: |