std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl
Определено в заголовке <cmath> |
||
|---|---|---|
| (1) | ||
float nextafter ( float from, float to ); double nextafter ( double from, double to ); long double nextafter ( long double from, long double to ); |
(с C++11) (до C++23) |
|
constexpr /* floating-point-type */
nextafter ( /* floating-point-type */ from,
/* floating-point-type */ to );
|
(с C++23) | |
float nextafterf( float from, float to ); |
(2) | (с C++11) (constexpr с C++23) |
long double nextafterl( long double from, long double to ); |
(3) | (с C++11) (constexpr с 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 ); |
(с C++11) (до C++23) |
|
constexpr /* floating-point-type */
nexttoward ( /* floating-point-type */ from,
long double to );
|
(с C++23) | |
float nexttowardf( float from, long double to ); |
(5) | (с C++11) (constexpr с C++23) |
long double nexttowardl( long double from, long double to ); |
(6) | (с C++11) (constexpr с C++23) |
| Дополнительные перегрузки | ||
Определено в заголовке <cmath> |
||
template< class Arithmetic1, class Arithmetic2 >
/* common-floating-point-type */
nextafter( Arithmetic1 from, Arithmetic2 to );
|
(A) | (с C++11) (constexpr с C++23) |
template< class Integer > double nexttoward( Integer from, long double to ); |
(B) | (с C++11) (constexpr с C++23) |
Возвращает следующее представимое значение from в направлении to.
from равно to, возвращается to. Библиотека предоставляет перегрузки std::nextafter для всех типов с плавающей запятой без cv-квалификаторов в качестве типа параметров from и to. (с C++23)
from равно to, возвращается to, преобразованное из long double в тип возвращаемого значения функции без потери диапазона или точности. | Библиотека предоставляет перегрузки | (с C++23) |
std::nextafter перегрузки предоставляются для всех других сочетаний типов арифметических типов.std::nexttoward перегрузки предоставляются для всех целочисленных типов, которые рассматриваются как double. Параметры
| from, to | - | значения с плавающей запятой или целые числа |
Значение возврата
Если не возникло ошибок, возвращается следующее представимое значение from в направлении to. Если from равно to, то возвращается to.
Если возникает ошибка диапазона из-за переполнения, возвращается ±HUGE_VAL, ±HUGE_VALF, или ±HUGE_VALL (с тем же знаком, что и from).
Если возникает ошибка диапазона из-за недотека, возвращается правильный результат.
Обработка ошибок
Ошибки сообщаются, как указано в math_errhandling.
Если реализация поддерживает арифметику с плавающей запятой IEEE (IEC 60559),
- если
fromконечно, но ожидаемый результат — бесконечность, возникаетFE_INEXACTиFE_OVERFLOW. - если
fromне равноtoи результат — субнормальное или нулевое значение, возникаетFE_INEXACTиFE_UNDERFLOW. - в любом случае возвращаемое значение не зависит от текущего режима округления.
- если
fromилиtoравно NaN, возвращается NaN.
Примечания
POSIX определяет, что условия переполнения и недотека являются ошибками диапазона (errno может быть установлено).
IEC 60559 рекомендует, что возвращается from всякий раз, когда from == to. Эти функции возвращают to вместо этого, что делает поведение вокруг нуля согласованным: std::nextafter(-0.0, +0.0) возвращает +0.0 и std::nextafter(+0.0, -0.0) возвращает -0.0.
std::nextafter обычно реализуется путём манипулирования представлением IEEE (glibc, musl).
Дополнительные std::nextafter перегрузки не обязаны быть предоставлены точно как в (A). Они должны быть достаточными, чтобы обеспечить для их первого аргумента num1 и второго аргумента num2:
| (до C++23) |
| Если Если такого типа с плавающей запятой с наибольшим рангом и подрангом не существует, тогда разрешение перегрузки не приводит к применимому кандидату из предоставленных перегрузок. | (с C++23) |
Дополнительные std::nexttoward перегрузки не обязаны быть предоставлены точно как в (B). Они должны быть достаточными, чтобы обеспечить для их аргумента num целочисленного типа, std::nexttoward(num) имеет тот же эффект, что и 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);
}Вывод:
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 для nextafter |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/math/nextafter