Defined in header <cmath> | ||
---|---|---|
(1) | ||
float nextafter ( float from, float to ); double nextafter ( double from, double to ); long double nextafter ( long double from, long double to ); | (since C++11) (until C++23) | |
constexpr /* floating-point-type */ nextafter ( /* floating-point-type */ from, /* floating-point-type */ to ); | (since C++23) | |
float nextafterf( float from, float to ); | (2) | (since C++11) (constexpr since C++23) |
long double nextafterl( long double from, long double to ); | (3) | (since C++11) (constexpr since 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 ); | (since C++11) (until C++23) | |
constexpr /* floating-point-type */ nexttoward ( /* floating-point-type */ from, long double to ); | (since C++23) | |
float nexttowardf( float from, long double to ); | (5) | (since C++11) (constexpr since C++23) |
long double nexttowardl( long double from, long double to ); | (6) | (since C++11) (constexpr since C++23) |
Additional overloads | ||
Defined in header <cmath> | ||
template< class Arithmetic1, class Arithmetic2 > /* common-floating-point-type */ nextafter( Arithmetic1 from, Arithmetic2 to ); | (A) | (since C++11) (constexpr since C++23) |
template< class Integer > double nexttoward( Integer from, long double to ); | (B) | (since C++11) (constexpr since C++23) |
Returns the next representable value of from
in the direction of to
.
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)
long double
std::nextafter
overloads are provided for all other combinations of arithmetic types.double
from, to | - | floating-point or integer values |
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.
Errors are reported as specified in math_errhandling
.
If the implementation supports IEEE floating-point arithmetic (IEC 60559),
from
is finite, but the expected result is an infinity, raises FE_INEXACT
and FE_OVERFLOW
from
does not equal to
and the result is subnormal or zero, raises FE_INEXACT
and FE_UNDERFLOW
from
or to
is NaN, NaN is returned 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
.
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 (A). They only need to be sufficient to ensure that for their first argument num1
and second argument num2
:
| (until C++23) |
If 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 (B). 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))
.
#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
C documentation for nextafter |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/math/nextafter