Existe-t-il un moyen d'obtenir par programme le double qui est le plus proche de 1.0, mais qui n'est pas réellement 1.0?
Une façon piratée de faire cela serait de mémoriser le double en un entier de même taille, puis d'en 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 (1.111111111111). Cependant, il existe des machines où les entiers sont stockés en petit-boutiste tandis que la virgule flottante est stockée en gros-boutiste, donc cela ne fonctionnera pas toujours.
c++
floating-point
floating-accuracy
jorgbrown
la source
la source
nextafter()
est la seule manière appropriée de réaliser ce qu'il veut.1.0000...
binaire est décrémenté0.111111....
et pour le normaliser, vous devez le décaler vers la gauche:1.11111...
ce qui vous oblige à décrémenter l'exposant. Et puis vous êtes à 2 ulp de 1.0. Donc non, soustraire un de la valeur intégrale ne vous donne PAS ce qui est demandé ici.Réponses:
En C et C ++, ce qui suit donne la valeur la plus proche de 1,0:
Notez cependant que dans les versions ultérieures de C ++,
limits.h
est déconseillé au profit declimits
. Mais alors, si vous utilisez de toute façon du code spécifique C ++, vous pouvez utiliserEt comme Jarod42 l'écrit dans sa réponse, depuis C99 ou C ++ 11, vous pouvez également utiliser
nextafter
:Bien sûr, en C ++, vous pouvez (et pour les versions ultérieures de C ++) inclure
cmath
et utiliser à lastd::nextafter
place.la source
Depuis C ++ 11, vous pouvez utiliser
nextafter
pour obtenir la prochaine valeur représentable dans une direction donnée:Démo
la source
std::ceil(std::nextafter(1., std::numeric_limits<double>::max()))
.nextafter
, et c'est ainsi que musl l'implémente au cas où quelqu'un d'autre voudrait voir comment c'est fait. En gros: un twiddling brut.En C, vous pouvez utiliser ceci:
DBL_EPSILON
est la différence entre 1 et la plus petite valeur supérieure à 1 représentable.Vous devrez l'imprimer à plusieurs chiffres pour voir la valeur réelle.
Sur ma plateforme,
printf("%.16lf",1.0+DBL_EPSILON)
donne1.0000000000000002
.la source
1.
la1'000'000
démonstration1.0
. BTW, il donne également la valeur la plus proche supérieure à 1, et non la valeur absolue la plus proche de 1 (qui est peut-être inférieure à 1). Je conviens donc que c'est une réponse partielle, mais je pensais que cela pourrait néanmoins y contribuer.En C ++, vous pouvez également utiliser ceci
la source