std::nextafter,std::nextafterf,std::nextafterl,std::nexttoward,std::nexttowardf,(3)

NAME
std::nextafter,std::nextafterf,std::nextafterl,std::nexttoward,std::nexttowardf, - std::nextafter,std::nextafterf,std::nextafterl,std::nexttoward,std::nexttowardf,

Synopsis
   Defined in header <cmath>
   float nextafter ( float from, float to ); (1) (since C++11)
                        (constexpr since C++23)
   float nextafterf( float from, float to ); (2) (since C++11)
                        (constexpr since C++23)
   double nextafter ( double from, double to ); (3) (since C++11)
                        (constexpr since C++23)
   long double nextafter ( long double from, long double (4) (since C++11)
   to ); (constexpr since C++23)
   long double nextafterl( long double from, long double (5) (since C++11)
   to ); (constexpr since C++23)
   Promoted nextafter ( Arithmetic1 from, Arithmetic2 to (6) (since C++11)
   ); (constexpr since C++23)
   float nexttoward ( float from, long double to ); (7) (since C++11)
                        (constexpr since C++23)
   float nexttowardf( float from, long double to ); (8) (since C++11)
                        (constexpr since C++23)
   double nexttoward ( double from, long double to ); (9) (since C++11)
                        (constexpr since C++23)
   long double nexttoward ( long double from, long double (10) (since C++11)
   to ); (constexpr since C++23)
   long double nexttowardl( long double from, long double (11) (since C++11)
   to ); (constexpr since C++23)
   double nexttoward ( IntegralType from, long double to (12) (since C++11)
   ); (constexpr since C++23)
   Returns the next representable value of from in the direction of to.
   1-5) If from equals to, to is returned.
   7-11) If from equals to, to is returned, converted from long double to the return
   type of the function without loss of range or precision.
   6) A set of overloads or a function template for all combinations of arguments of
   arithmetic type not covered by (1-5). If any argument has integral type, it is cast
   to double. If any argument is long double, then the return type Promoted is also
   long double, otherwise the return type is always double.
   12) A set of overloads or a function template accepting the from argument of any
   integral type. Equivalent to (9) (the argument is cast to double).

Parameters
   from, to - floating point values

Return value
   If no errors occur, the next representable value of from in the direction of to. is
   returned. If from equals to, then to is returned.
   If a range error due to overflow occurs, ±HUGE_VAL, ±HUGE_VALF, or ±HUGE_VALL is
   returned (with the same sign as from)
   If a range error occurs due to underflow, the correct result is returned.

Error handling
   Errors are reported as specified in math_errhandling.
   If the implementation supports IEEE floating-point arithmetic (IEC 60559),
     * if from is finite, but the expected result is an infinity, raises FE_INEXACT and
       FE_OVERFLOW
     * if from does not equal to and the result is subnormal or zero, raises FE_INEXACT
       and FE_UNDERFLOW
     * in any case, the returned value is independent of the current rounding mode
     * if either from or to is NaN, NaN is returned

Notes
   POSIX specifies that the overflow and the underflow conditions are range errors
   (errno may be set).
   IEC 60559 recommends that from is returned whenever from == to. These functions
   return to instead, which makes the behavior around zero consistent:
   std::nextafter(-0.0, +0.0) returns +0.0 and std::nextafter(+0.0, -0.0) returns -0.0.
   nextafter is typically implemented by manipulation of IEEE representation (glibc,
   musl).

Example
// Run this code
 #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 << "The next representable float after " << std::setprecision(20) << from1
               << " is " << to1
               << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat;
     float from2 = 1, to2 = std::nextafter(from2, 2.f);
     std::cout << "The next representable float after " << from2 << " is " << to2
               << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat;
     double from3 = std::nextafter(0.1, 0), to3 = 0.1;
     std::cout << "The number 0.1 lies between two valid doubles:\n"
               << std::setprecision(56) << " " << from3
               << std::hexfloat << " (" << from3 << ')' << std::defaultfloat
               << "\nand " << to3 << std::hexfloat << " (" << to3 << ")\n"
               << std::defaultfloat << std::setprecision(20);
     std::cout << "\nDifference between nextafter and nexttoward:\n";
     long double dir = std::nextafter(from1, 1.0L); // first subnormal long double
     float x = std::nextafter(from1, dir); // first converts dir to float, giving 0
     std::cout << "With nextafter, next float after " << from1 << " is " << x << '\n';
     x = std::nexttoward(from1, dir);
     std::cout << "With nexttoward, next float after " << from1 << " is " << x << '\n';
     std::cout << "\nSpecial values:\n";
     {
         // #pragma STDC FENV_ACCESS ON
         std::feclearexcept(FE_ALL_EXCEPT);
         double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY);
         std::cout << "The next representable double after " << std::setprecision(6)
                   << from4 << std::hexfloat << " (" << from4 << ')'
                   << std::defaultfloat << " is " << to4
                   << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat;
         if(std::fetestexcept(FE_OVERFLOW)) std::cout << " raised FE_OVERFLOW\n";
         if(std::fetestexcept(FE_INEXACT)) std::cout << " raised FE_INEXACT\n";
     } // end FENV_ACCESS block
     float from5 = 0.0, to5 = std::nextafter(from5, -0.0);
     std::cout << "std::nextafter(+0.0, -0.0) gives " << 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) gives " << std::fixed << std::setprecision(6) << to
                       << "; Δ = " << Δ << '\n';
     };
     precision_loss_demo("\nPrecision loss demo for float:\n", 10.0f);
     precision_loss_demo("\nPrecision loss demo for double:\n", 10.0e9);
     precision_loss_demo("\nPrecision loss demo for long double:\n", 10.0e17L);
 }

Output:
 The next representable float after 0 is 1.4012984643248170709e-45 (0x1p-149)
 The next representable float after 1 is 1.0000001192092895508 (0x1.000002p+0)
 The number 0.1 lies between two valid doubles:
     0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
 and 0.1000000000000000055511151231257827021181583404541015625 (0x1.999999999999ap-4)
 Difference between nextafter and nexttoward:
 With nextafter, next float after 0 is 0
 With nexttoward, next float after 0 is 1.4012984643248170709e-45
 Special values:
 The next representable double after 1.79769e+308 (0x1.fffffffffffffp+1023) is inf (inf)
    raised FE_OVERFLOW
    raised FE_INEXACT
 std::nextafter(+0.0, -0.0) gives -0.000000
 Precision loss demo for float:
 nextafter(1e+01, INF) gives 10.000001; Δ = 0.000001
 nextafter(1e+02, INF) gives 100.000008; Δ = 0.000008
 nextafter(1e+03, INF) gives 1000.000061; Δ = 0.000061
 nextafter(1e+04, INF) gives 10000.000977; Δ = 0.000977
 nextafter(1e+05, INF) gives 100000.007812; Δ = 0.007812
 nextafter(1e+06, INF) gives 1000000.062500; Δ = 0.062500
 nextafter(1e+07, INF) gives 10000001.000000; Δ = 1.000000
 nextafter(1e+08, INF) gives 100000008.000000; Δ = 8.000000
 Precision loss demo for double:
 nextafter(1e+10, INF) gives 10000000000.000002; Δ = 0.000002
 nextafter(1e+11, INF) gives 100000000000.000015; Δ = 0.000015
 nextafter(1e+12, INF) gives 1000000000000.000122; Δ = 0.000122
 nextafter(1e+13, INF) gives 10000000000000.001953; Δ = 0.001953
 nextafter(1e+14, INF) gives 100000000000000.015625; Δ = 0.015625
 nextafter(1e+15, INF) gives 1000000000000000.125000; Δ = 0.125000
 nextafter(1e+16, INF) gives 10000000000000002.000000; Δ = 2.000000
 Precision loss demo for long double:
 nextafter(1e+18, INF) gives 1000000000000000000.062500; Δ = 0.062500
 nextafter(1e+19, INF) gives 10000000000000000001.000000; Δ = 1.000000
 nextafter(1e+20, INF) gives 100000000000000000008.000000; Δ = 8.000000

See also