std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl
|
Défini dans l'en-tête
<cmath>
|
||
| (1) | ||
|
float
nextafter
(
float
from,
float
to
)
;
double
nextafter
(
double
from,
double
to
)
;
|
(depuis C++11)
(jusqu'à C++23) |
|
|
constexpr
/* floating-point-type */
nextafter
(
/* floating-point-type */
from,
|
(depuis C++23) | |
|
float
nextafterf
(
float
from,
float
to
)
;
|
(2) |
(depuis C++11)
(constexpr depuis C++23) |
|
long
double
nextafterl
(
long
double
from,
long
double
to
)
;
|
(3) |
(depuis C++11)
(constexpr depuis C++23) |
| (4) | ||
|
float
nexttoward
(
float
from,
long
double
to
)
;
double
nexttoward
(
double
from,
long
double
to
)
;
|
(depuis C++11)
(jusqu'à C++23) |
|
|
constexpr
/* floating-point-type */
nexttoward
(
/* floating-point-type */
from,
|
(depuis C++23) | |
|
float
nexttowardf
(
float
from,
long
double
to
)
;
|
(5) |
(depuis C++11)
(constexpr depuis C++23) |
|
long
double
nexttowardl
(
long
double
from,
long
double
to
)
;
|
(6) |
(depuis C++11)
(constexpr depuis C++23) |
|
Défini dans l'en-tête
<cmath>
|
||
|
template
<
class
Arithmetic1,
class
Arithmetic2
>
/* common-floating-point-type */
|
(A) |
(depuis C++11)
(constexpr depuis C++23) |
|
template
<
class
Integer
>
double nexttoward ( Integer from, long double to ) ; |
(B) |
(depuis C++11)
(constexpr depuis C++23) |
Retourne la valeur représentable suivante de from dans la direction de to .
std::nextafter
pour tous les types à virgule flottante non qualifiés cv comme type des paramètres
from
et
to
.
(depuis C++23)
|
La bibliothèque fournit des surcharges de
|
(depuis C++23) |
std::nextafter
sont fournies pour toutes les autres combinaisons de types arithmétiques.
std::nexttoward
sont fournies pour tous les types entiers, qui sont traités comme
double
.
Table des matières |
Paramètres
| de, à | - | valeurs à virgule flottante ou entières |
Valeur de retour
Si aucune erreur ne se produit, la valeur représentable suivante de from dans la direction de to est retournée. Si from est égal à to , alors to est retourné.
Si une erreur de plage due à un dépassement de capacité se produit,
±HUGE_VAL
,
±HUGE_VALF
, ou
±HUGE_VALL
est retourné (avec le même signe que
from
).
Si une erreur de plage se produit en raison d'un dépassement inférieur, le résultat correct est retourné.
Gestion des erreurs
Les erreurs sont signalées comme spécifié dans math_errhandling .
Si l'implémentation prend en charge l'arithmétique à virgule flottante IEEE (IEC 60559),
- si from est fini, mais que le résultat attendu est un infini, lève FE_INEXACT et FE_OVERFLOW .
- si from n'est pas égal à to et que le résultat est sous-normal ou zéro, lève FE_INEXACT et FE_UNDERFLOW .
- dans tous les cas, la valeur retournée est indépendante du mode d'arrondi actuel.
- si from ou to est NaN, NaN est retourné.
Notes
POSIX spécifie que les conditions de dépassement supérieur et de dépassement inférieur sont des erreurs de plage ( errno peut être défini).
La norme IEC 60559 recommande que from soit retourné lorsque from == to . Ces fonctions retournent to à la place, ce qui rend le comportement autour de zéro cohérent : std :: nextafter ( - 0.0 , + 0.0 ) retourne + 0.0 et std :: nextafter ( + 0.0 , - 0.0 ) retourne - 0.0 .
std::nextafter
est généralement implémenté par manipulation de la représentation IEEE (
glibc
,
musl
).
Les surcharges supplémentaires de
std::nextafter
ne sont pas requises d'être fournies exactement comme
(A)
. Elles doivent seulement être suffisantes pour garantir que pour leur premier argument
num1
et second argument
num2
:
|
(jusqu'en C++23) |
|
Si
num1
et
num2
ont des types arithmétiques, alors
std
::
nextafter
(
num1, num2
)
a le même effet que
std
::
nextafter
(
static_cast
<
/*common-floating-point-type*/
>
(
num1
)
,
Si aucun tel type à virgule flottante avec le plus grand rang et la plus grande sous-catégorie n'existe, alors la résolution de surcharge ne résulte pas en un candidat utilisable parmi les surcharges fournies. |
(depuis C++23) |
Les surcharges supplémentaires de
std::nexttoward
ne sont pas tenues d'être fournies exactement comme
(B)
. Elles doivent seulement être suffisantes pour garantir que pour leur argument
num
de type entier,
std
::
nexttoward
(
num
)
ait le même effet que
std
::
nexttoward
(
static_cast
<
double
>
(
num
)
)
.
Exemple
#include <cfenv> #include <cfloat> #include <cmath> #include <concepts> #include <iomanip> #include <iostream> int main() { float from1 = 0, to1 = std::nextafter(from1, 1.f); std::cout << "Le prochain flottant représentable après " << std::setprecision(20) << from1 << " est " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "Le prochain flottant représentable après " << from2 << " est " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "Le nombre 0.1 se situe entre deux doubles valides :\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\net " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nDifférence entre nextafter et nexttoward:\n"; long double dir = std::nextafter(from1, 1.0L); // premier long double sous-normal float x = std::nextafter(from1, dir); // convertit d'abord dir en float, donnant 0 std::cout << "Avec nextafter, prochain flottant après " << from1 << " est " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "Avec nexttoward, prochain flottant après " << from1 << " est " << x << '\n'; std::cout << "\nValeurs spéciales :\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "Le prochain double représentable après " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " est " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " levé FE_OVERFLOW\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " a déclenché FE_INEXACT\n"; } // fin du bloc FENV_ACCESS float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) donne " << std::fixed << to5 << '\n'; auto precision_loss_demo = []<std::floating_point Fp>(const auto rem, const Fp start) { std::cout << rem; for (Fp from = start, to, Δ; (Δ = (to = std::nextafter(from, +INFINITY)) - from) < Fp(10.0); from *= Fp(10.0)) std::cout << "nextafter(" << std::scientific << std::setprecision(0) << from << ", INF) donne " << std::fixed << std::setprecision(6) << to << "; Δ = " << Δ << '\n'; }; precision_loss_demo("\nDémonstration de perte de précision pour float:\n", 10.0f); precision_loss_demo("\nDémonstration de perte de précision pour double :\n", 10.0e9); precision_loss_demo("\nDémonstration de perte de précision pour long double :\n", 10.0e17L); }
Sortie :
Le prochain flottant représentable après 0 est 1.4012984643248170709e-45 (0x1p-149)
Le prochain flottant représentable après 1 est 1.0000001192092895508 (0x1.000002p+0)
Le nombre 0.1 se situe entre deux doubles valides :
0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
et 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
Différence entre nextafter et nexttoward :
Avec nextafter, le prochain flottant après 0 est 0
Avec nexttoward, le prochain flottant après 0 est 1.4012984643248170709e-45
Valeurs spéciales :
Le prochain double représentable après 1.79769e+308 (0x1.fffffffffffffp+1023) est inf (inf)
a levé FE_OVERFLOW
a levé FE_INEXACT
std::nextafter(+0.0, -0.0) donne -0.000000
Démonstration de perte de précision pour float :
nextafter(1e+01, INF) donne 10.000001 ; Δ = 0.000001
nextafter(1e+02, INF) donne 100.000008 ; Δ = 0.000008
nextafter(1e+03, INF) donne 1000.000061 ; Δ = 0.000061
nextafter(1e+04, INF) donne 10000.000977 ; Δ = 0.000977
nextafter(1e+05, INF) donne 100000.007812 ; Δ = 0.007812
nextafter(1e+06, INF) donne 1000000.062500 ; Δ = 0.062500
nextafter(1e+07, INF) donne 10000001.000000 ; Δ = 1.000000
nextafter(1e+08, INF) donne 100000008.000000 ; Δ = 8.000000
Démonstration de perte de précision pour double :
nextafter(1e+10, INF) donne 10000000000.000002 ; Δ = 0.000002
nextafter(1e+11, INF) donne 100000000000.000015 ; Δ = 0.000015
nextafter(1e+12, INF) donne 1000000000000.000122 ; Δ = 0.000122
nextafter(1e+13, INF) donne 10000000000000.001953 ; Δ = 0.001953
nextafter(1e+14, INF) donne 100000000000000.015625 ; Δ = 0.015625
nextafter(1e+15, INF) donne 1000000000000000.125000 ; Δ = 0.125000
nextafter(1e+16, INF) donne 10000000000000002.000000 ; Δ = 2.000000
Démonstration de perte de précision pour long double :
nextafter(1e+18, INF) donne 1000000000000000000.062500 ; Δ = 0.062500
nextafter(1e+19, INF) donne 10000000000000000001.000000 ; Δ = 1.000000
nextafter(1e+20, INF) donne 100000000000000000008.000000 ; Δ = 8.000000
Voir aussi
|
Documentation C
pour
nextafter
|