std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl
Defined in header
<cmath>
|
||
(1) | ||
float
nextafter
(
float
from,
float
to
)
;
double
nextafter
(
double
from,
double
to
)
;
|
(since C++11)
(until C++23) |
|
constexpr
/* floating-point-type */
nextafter
(
/* floating-point-type */
from,
|
(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
)
;
|
(since C++11)
(until C++23) |
|
constexpr
/* floating-point-type */
nexttoward
(
/* floating-point-type */
from,
|
(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) |
Defined in header
<cmath>
|
||
template
<
class
Arithmetic1,
class
Arithmetic2
>
/* common-floating-point-type */
|
(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 .
std::nextafter
for all cv-unqualified floating-point types as the type of the parameters
from
and
to
.
(since C++23)
The library provides overloads of
|
(since C++23) |
std::nextafter
overloads are provided for all other combinations of arithmetic types.
std::nexttoward
overloads are provided for all integer types, which are treated as
double
.
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 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
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
)
,
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
)
)
.
Example
#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
C documentation
for
nextafter
|