87 votes

Quel est le double le plus proche de 1.0, ce n'est pas 1.0?

Est-il un moyen de programmation pour obtenir le double de ce qui est le plus proche de 1.0, mais n'est pas réellement 1.0?

Un hacky façon de le faire serait de memcpy le double pour une même taille d'un entier, puis de soustraire un. La façon IEEE754 à virgule flottante formats de travail, ce serait la fin de la hausse de la diminution de l'exposant par l'un tandis que l'évolution de la partie fractionnaire de tous les zéros (1.000000000000) à tous ceux (1.111111111111). Cependant, il existe des machines où les entiers sont stockés little-endian tout en virgule flottante est stocké big-endian, donc qui ne fonctionne pas toujours.

139voto

Jarod42 Points 15729

Depuis C ++11, vous pouvez utiliser nextafter pour obtenir la prochaine valeur représentable dans une direction donnée:

 std::nextafter(1., 0.); // 0.99999999999999989
std::nextafter(1., 2.); // 1.0000000000000002
 

Démo

25voto

barak manos Points 10969

En C, vous pouvez utiliser ceci:

 #include <float.h>
...
double value = 1.0+DBL_EPSILON;
 

DBL_EPSILON est la différence entre 1 et la plus petite valeur supérieure à 1 pouvant être représentée.

Vous devrez l’imprimer sur plusieurs chiffres pour voir la valeur réelle.

Sur ma plate-forme, printf("%.16lf",1.0+DBL_EPSILON) donne 1.0000000000000002 .

22voto

celtschk Points 9699

En C et C++, le suivant donne la valeur la plus proche de 1.0:

#include <limits.h>

double closest_to_1 = 1.0 - DBL_EPSILON/FLT_RADIX;

Notez cependant que dans les versions ultérieures de C++, limits.h est déconseillée en faveur de l' climits. Mais alors, si vous êtes à l'aide de C++ code spécifique de toute façon, vous pouvez utiliser

#include <limits>

typedef std::numeric_limits<double> lim_dbl;
double closest_to_1 = 1.0 - lim_dbl::epsilon()/lim_dbl::radix;

Et comme Jarod42 écrit dans sa réponse, depuis C99 ou C++11, vous pouvez également utiliser nextafter:

#include <math.h>

double closest_to_1 = nextafter(1.0, 0.0);

Bien sûr, en C++, vous pouvez (et pour plus tard, C++ versions) comprennent cmath et l'utilisation std::nextafter à la place.

4voto

Lưu Vĩnh Phúc Points 3183

En C ++, vous pouvez également utiliser cette

 1 + std::numeric_limits<double>::epsilon()
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X