Namespaces
Variants

std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl

From cppreference.net
Common mathematical functions
Nearest integer floating point operations
(C++11)
(C++11)
(C++11) (C++11) (C++11)
Floating point manipulation functions
(C++11) (C++11)
(C++11)
(C++11)
nextafter nexttoward
(C++11) (C++11)
(C++11)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
Défini dans l'en-tête <cmath>
(1)
float nextafter ( float from, float to ) ;

double nextafter ( double from, double to ) ;

long double nextafter ( long double from, long double to ) ;
(depuis C++11)
(jusqu'à C++23)
constexpr /* floating-point-type */

nextafter ( /* floating-point-type */ from,

/* floating-point-type */ to ) ;
(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 ) ;

long double nexttoward ( long double from, long double to ) ;
(depuis C++11)
(jusqu'à C++23)
constexpr /* floating-point-type */

nexttoward ( /* floating-point-type */ from,

long double to ) ;
(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 */

nextafter ( Arithmetic1 from, Arithmetic2 to ) ;
(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 .

1-3) Si from est égal à to , to est retourné. La bibliothèque fournit des surcharges de std::nextafter pour tous les types à virgule flottante non qualifiés cv comme type des paramètres from et to . (depuis C++23)
4-6) Si from est égal à to , to est retourné, converti de long double vers le type de retour de la fonction sans perte de plage ou de précision.

La bibliothèque fournit des surcharges de std::nexttoward pour tous les types à virgule flottante non qualifiés cv comme type du paramètre from . Cependant, un appel à std::nexttoward est mal formé si l'argument correspondant à from a un type étendu à virgule flottante , car la valeur représentable suivante (ou to ) n'est pas garantie d'être représentable comme long double .

(depuis C++23)
A) Des surcharges supplémentaires de std::nextafter sont fournies pour toutes les autres combinaisons de types arithmétiques.
B) Des surcharges supplémentaires de 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 :

  • Si num1 ou num2 a le type long double , alors std :: nextafter ( num1, num2 ) a le même effet que std :: nextafter ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) )
    .
  • Sinon, si num1 et/ou num2 a le type double ou un type entier, alors std :: nextafter ( num1, num2 ) a le même effet que std :: nextafter ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) )
    .
  • Sinon, si num1 ou num2 a le type float , alors std :: nextafter ( num1, num2 ) a le même effet que std :: nextafter ( static_cast < float > ( num1 ) ,
    static_cast < float > ( 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 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) )
, où /*common-floating-point-type*/ est le type à virgule flottante ayant le plus grand rang de conversion en virgule flottante et la plus grande sous-catégorie de conversion en virgule flottante entre les types de num1 et num2 , les arguments de type entier sont considérés comme ayant le même rang de conversion en virgule flottante que double .

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