El título es bastante autoexplicativo, la entrada tiene doble valor y quiero agregar/sustraer la menor cantidad posible.Cómo encontrar el valor doble siguiente/anterior más próximo (numeric_limits :: épsilon para el número dado)
Respuesta
Si su compilador implementa funciones matemáticas de C99/C++ 11, se puede utilizar el nextafter
:
#include <cfloat> // DBL_MAX
#include <cmath> // std::nextafter
double x = 0.1;
// next representable number after x in the direction of DBL_MAX
double xPlusSmallest = std::nextafter(x, DBL_MAX);
Incluso si su compilador no lo soporta, probablemente tiene un intrínseco para eso. (MSVC ha tenido _nextafter
desde el año 2005, por ejemplo CCG probablemente lo implementa como estándar..)
Si el compilador no lo soporta, pero Boost está disponible para usted, usted puede hacer esto:
#include <boost/math/special_functions/next.hpp> // boost::float_next
double x = 0.1;
// next representable number after x
double xPlusSmallest = boost::math::float_next(x);
lo que equivale a esto (C99 emulando):
#include <boost/math/special_functions/next.hpp> // boost::nextafter
#include <cfloat> // DBL_MAX
double x = 0.1;
// next representable number after x in the direction of DBL_MAX
double xPlusSmallest = boost::math::nextafter(x, DBL_MAX);
y si ninguno de los trabajos para usted, sólo tendrá que abrir una grieta en la cabecera Boost y copiarlo.
Gracias por la buena respuesta, ya que ' m usando boost usaré su método. – kovarex
#define FLT_MIN 1.175494351e-38F /* min positive value */
#define FLT_MAX 3.402823466e+38F /* max value */
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */
#define DBL_MAX 1.7976931348623158e+308 /* max value */
Creo que el OP quiere saber la diferencia * más pequeña posible * entre dos números flotantes/dobles, no los valores mínimos/máximos. –
pero también muestra cómo los valores mínimos son menores que los almacenados en el archivo float.h –
@AlexZ K. Luego depende de la FPU. El enlace que di muestra la precisión con la que FPU puede procesar. Y entonces siento que la diferencia mínima puede ser el valor positivo mínimo que se puede procesar –
Aquí hay un truco muy sucio que no es legal y solo funciona si su plataforma usa flotadores IEEE754: La representación binaria del flotador se ordena de la misma manera que el valor flotante, por lo que puede incrementar la representación binaria:
double x = 1.25;
uint64_t * const p = reinterpret_cast<uint64_t*>(&x);
++*p; // undefined behaviour! but it gets the next value
// now x has the next value
se puede lograr el mismo efecto totalmente contrario por hacer las habituales gimnasia copia binaria para obtener un valor adecuado uint64_t
. Asegúrate también de verificar cero, infinito y NaN correctamente.
He oído que GCC incluso reemplazará 'memcpy' entre tipos en aliasing cuando sea posible, aunque eso puede ser solo un mito. – GManNickG
¿Esto manejará correctamente el desbordamiento de mantisa? ¿Qué sucede si la representación binaria es .111111111 * 2^k? ¿Da 0.00000000 * 2^{k + 1}? –
@Alexandre C: Sí, lo hace. – user763305
¿Qué tal:
x += fabs(x) * std::numeric_limits<double>::epsilon();
¿Multiplicar por tipo? – GManNickG
Supongamos que quiere agregar ':: min()', esto no funcionará para los números desnormalizados, y necesita una prueba para el caso regular. ¿Qué garantiza IEEE 754 sobre los ULP en multiplicación y adición? Yo pensaría que los números '1.5 * 2^n ≤ x <2^n + 1' redondearían hasta el doble del épsilon deseado después de la multiplicación, aunque debería funcionar con un fusionado multiple-add. – Potatoswatter
Whoops - simplemente me olvidé de escribir épsilon ... corregido ahora –
- 1. próximo más alto/más bajo IEEE precisión doble número
- 2. Valor para épsilon en Python
- 3. Modelado de infinito para el valor doble más grande
- 4. Encontrar el número en una matriz que está más cerca de un número dado
- 5. Cuál debe ser el valor épsilon cuando se realiza una comparación igual de valor doble
- 6. Intentando escribir un código para encontrar la máquina épsilon
- 7. ¿Modificar un número dado para encontrar la suma requerida?
- 8. ¿Cómo puedo encontrar el número primo más cercano?
- 9. Encontrar la fecha para un número de semana dado
- 10. ¿Cómo decidir si el valor dado es flotante o doble en Java?
- 11. Javascript - cómo redondear al número entero más próximo
- 12. Java - Decimal Format.parse para devolver el valor doble con el número especificado de posiciones decimales
- 13. de la lista de números enteros, obtiene el número más cercano a un valor dado
- 14. Buscar el próximo artículo más bajo en una lista ordenada
- 15. Encontrar un número primo después de un número dado
- 16. Encontrar el hermano anterior y el próximo controla
- 17. Encontrar las teclas más cercanas a un valor dado para los mapas clasificados de Clojure
- 18. SQL - ¿Cómo encontrar el número más alto en una columna?
- 19. Fecha de PHP; ¿Cómo encontrar el próximo año?
- 20. Algoritmo para encontrar el número primo más grande más pequeño que x
- 21. ¿Cómo encontrar el número más alto en una matriz?
- 22. ¿Cómo determina Linux el próximo PID?
- 23. ¿Cómo encontrar qué valor es el más cercano a un número en C?
- 24. usando jQuery, ¿Cómo puedo encontrar el valor más cercano de una matriz, a un número especificado
- 25. ¿Encontrar k vecinos más cercanos para un vector dado?
- 26. Cómo obtener el carácter para un valor de ascii dado
- 27. Dado un número decimal, encuentre el multiplicador de enteros más pequeño que dé un resultado entero
- 28. Cómo convertir el número de Int a Número doble?
- 29. convertir el valor doble en el valor binario
- 30. ¿Cómo encuentro elemento más próximo con jQuery
Would 'doble lado = valor + std :: :: numeric_limits épsilon() work'? ¿O me estoy perdiendo algo? –
rve
@rve: En algún punto que deja de aumentar el valor (no tiene ningún efecto), porque el valor con el que comenzó es una mejor aproximación del nuevo valor, que no se puede almacenar con precisión. Entonces te quedas atascado en un ciclo de no llegar del siguiente número. – GManNickG
@rve, no, ya que es épsilon para el doble con valor 1, el épsilon se hace más y más grande con números más altos, vea http://en.wikipedia.org/wiki/Double-precision_floating-point_format – kovarex