Skip to main content

Nextafter

Defined in header <cmath>.

Description

If from equals to, to is returned.
The library provides overloads of std::nextafter for all cv-unqualified floating-point types as the type of the parameters from and to  (since C++23).

4-6) If from equals to, to is returned, converted from long double to the return type of the function without loss of range or precision.
The library provides overloads of std::nexttoward for all cv-unqualified floating-point types as the type of the parameter from  (since C++23).

  • A) Additional std::nextafter overloads are provided for all other combinations of arithmetic types.
  • B) Additional std::nexttoward overloads are provided for all integer types, which are treated as double.

Declarations

// 1)
constexpr /* floating-point-type */
nextafter ( /* floating-point-type */ from,
/* floating-point-type */ to );
// 2)
constexpr float nextafterf( float from, float to );
// 3)
constexpr long double nextafterl( long double from, long double to );
// 4)
constexpr /* floating-point-type */
nexttoward ( /* floating-point-type */ from,
long double to );
// 5)
constexpr float nexttowardf( float from, long double to );
// 6)
constexpr long double nexttowardl( long double from, long double to );
Additional Overloads
// 7)
template< class Arithmetic1, class Arithmetic2 >
constexpr /* common-floating-point-type */
nextafter( Arithmetic1 from, Arithmetic2 to );
// 8)
template< class Integer >
constexpr double nexttoward( Integer from, long double to );

Parameters

from, to - floating-point or integer 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] (https://pubs.opengroup.org/onlinepubs/9699919799/functions/nextafter.html) 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.

std::nextafter is typically implemented by manipulation of IEEE representation (glibc, musl).

The additional std::nextafter overloads are not required to be provided exactly as Additional Overloads. They only need to be sufficient to ensure that for their first argument num1 and second argument num2:

If num1 or num2 has type long double, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<long double>(num1), static_cast<long double>(num2)).

Otherwise, if num1 and/or num2 has type double or an integer type, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<double>(num1), static_cast<double>(num2)).

Otherwise, if num1 or num2 has type float, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<float>(num1), static_cast<float>(num2)). (until C++23)

If num1 and num2 have arithmetic types, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast</* common-floating-point-type */>(num1), static_cast</* common-floating-point-type */>(num2)) ,

where /* common-floating-point-type */ is the floating-point type with the greatest floating-point conversion rank and greatest floating-point conversion subrank between the types of num1 and num2, arguments of integer type are considered to have the same floating-point conversion rank as double.

If no such floating-point type with the greatest rank and subrank exists, then overload resolution does not result in a usable candidate from the overloads provided. (since C++23)

The additional std::nexttoward overloads are not required to be provided exactly as Additional Overloads. They only need to be sufficient to ensure that for their argument num of integer type, std::nexttoward(num) has the same effect as std::nexttoward(static_cast<double>(num)).

Examples

#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);
}

Result
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

Nextafter

Defined in header <cmath>.

Description

If from equals to, to is returned.
The library provides overloads of std::nextafter for all cv-unqualified floating-point types as the type of the parameters from and to  (since C++23).

4-6) If from equals to, to is returned, converted from long double to the return type of the function without loss of range or precision.
The library provides overloads of std::nexttoward for all cv-unqualified floating-point types as the type of the parameter from  (since C++23).

  • A) Additional std::nextafter overloads are provided for all other combinations of arithmetic types.
  • B) Additional std::nexttoward overloads are provided for all integer types, which are treated as double.

Declarations

// 1)
constexpr /* floating-point-type */
nextafter ( /* floating-point-type */ from,
/* floating-point-type */ to );
// 2)
constexpr float nextafterf( float from, float to );
// 3)
constexpr long double nextafterl( long double from, long double to );
// 4)
constexpr /* floating-point-type */
nexttoward ( /* floating-point-type */ from,
long double to );
// 5)
constexpr float nexttowardf( float from, long double to );
// 6)
constexpr long double nexttowardl( long double from, long double to );
Additional Overloads
// 7)
template< class Arithmetic1, class Arithmetic2 >
constexpr /* common-floating-point-type */
nextafter( Arithmetic1 from, Arithmetic2 to );
// 8)
template< class Integer >
constexpr double nexttoward( Integer from, long double to );

Parameters

from, to - floating-point or integer 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] (https://pubs.opengroup.org/onlinepubs/9699919799/functions/nextafter.html) 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.

std::nextafter is typically implemented by manipulation of IEEE representation (glibc, musl).

The additional std::nextafter overloads are not required to be provided exactly as Additional Overloads. They only need to be sufficient to ensure that for their first argument num1 and second argument num2:

If num1 or num2 has type long double, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<long double>(num1), static_cast<long double>(num2)).

Otherwise, if num1 and/or num2 has type double or an integer type, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<double>(num1), static_cast<double>(num2)).

Otherwise, if num1 or num2 has type float, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast<float>(num1), static_cast<float>(num2)). (until C++23)

If num1 and num2 have arithmetic types, then
std::nextafter(num1, num2) has the same effect as
std::nextafter(static_cast</* common-floating-point-type */>(num1), static_cast</* common-floating-point-type */>(num2)) ,

where /* common-floating-point-type */ is the floating-point type with the greatest floating-point conversion rank and greatest floating-point conversion subrank between the types of num1 and num2, arguments of integer type are considered to have the same floating-point conversion rank as double.

If no such floating-point type with the greatest rank and subrank exists, then overload resolution does not result in a usable candidate from the overloads provided. (since C++23)

The additional std::nexttoward overloads are not required to be provided exactly as Additional Overloads. They only need to be sufficient to ensure that for their argument num of integer type, std::nexttoward(num) has the same effect as std::nexttoward(static_cast<double>(num)).

Examples

#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);
}

Result
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