Existe-t-il un moyen d'obtenir par programme le double le plus proche de 1.0, mais qui n'est pas réellement 1.0?
Une façon hacky de le faire serait de mémoriser le double en un entier de même taille, puis de soustraire un. La façon dont les formats à virgule flottante IEEE754 fonctionnent, cela finirait par diminuer l'exposant de un tout en changeant la partie fractionnaire de tous les zéros (1.000000000000) à tous les (1.111111111111). Cependant, il existe des machines où les nombres entiers sont stockés en petit bout, tandis que les nombres à virgule flottante sont stockés en gros bout, de sorte que cela ne fonctionnera pas toujours.
En C et C++, ce qui suit 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é au profit de climits
. Mais si vous utilisez de toute façon du code spécifique C++, 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 l'é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 les versions C++ ultérieures devraient) inclure cmath
et utiliser std::nextafter
au lieu.
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 qui est représentable.
Vous devrez l'imprimer sur plusieurs chiffres afin de voir la valeur réelle.
Sur ma plateforme, printf("%.16lf",1.0+DBL_EPSILON)
donne 1.0000000000000002
.
En C++, vous pouvez également utiliser ceci
1 + std::numeric_limits<double>::epsilon()