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
)
;
|
(C++11 起)
(C++23 前) |
|
|
constexpr
/* floating-point-type */
nextafter
(
/* floating-point-type */
from,
|
(C++23 起) | |
|
float
nextafterf
(
float
from,
float
to
)
;
|
(2) |
(C++11 起)
(C++23 起 constexpr) |
|
long
double
nextafterl
(
long
double
from,
long
double
to
)
;
|
(3) |
(C++11 起)
(C++23 起 constexpr) |
| (4) | ||
|
float
nexttoward
(
float
from,
long
double
to
)
;
double
nexttoward
(
double
from,
long
double
to
)
;
|
(C++11 起)
(C++23 前) |
|
|
constexpr
/* floating-point-type */
nexttoward
(
/* floating-point-type */
from,
|
(C++23 起) | |
|
float
nexttowardf
(
float
from,
long
double
to
)
;
|
(5) |
(C++11 起)
(C++23 起 constexpr) |
|
long
double
nexttowardl
(
long
double
from,
long
double
to
)
;
|
(6) |
(C++11 起)
(C++23 起 constexpr) |
|
定义于头文件
<cmath>
|
||
|
template
<
class
Arithmetic1,
class
Arithmetic2
>
/* common-floating-point-type */
|
(A) |
(C++11 起)
(C++23 起 constexpr) |
|
template
<
class
Integer
>
double nexttoward ( Integer from, long double to ) ; |
(B) |
(C++11 起)
(C++23 起 constexpr) |
返回 from 在朝向 to 方向上的下一个可表示值。
std::nextafter
的重载,将参数
from
和
to
的类型作为浮点类型。
(C++23 起)
|
标准库为所有无 cv 限定的浮点类型提供了
|
(since 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 == to 时返回 from 。但这些函数会返回 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 前) |
|
若
num1
和
num2
具有算术类型,则
std
::
nextafter
(
num1, num2
)
的效果等同于
std
::
nextafter
(
static_cast
<
/*common-floating-point-type*/
>
(
num1
)
,
若不存在具有最高等级和子等级的此类浮点类型,则 重载决议 不会从提供的重载中得到可用候选。 |
(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 << "0之后可表示的下一个浮点数为 " << std::setprecision(20) << from1 << " 是 " << to1 << std::hexfloat << " (" << to1 << ")\n" << std::defaultfloat; float from2 = 1, to2 = std::nextafter(from2, 2.f); std::cout << "1之后可表示的下一个浮点数为 " << from2 << " 是 " << to2 << std::hexfloat << " (" << to2 << ")\n" << std::defaultfloat; double from3 = std::nextafter(0.1, 0), to3 = 0.1; std::cout << "数字0.1位于两个有效双精度数之间:\n" << std::setprecision(56) << " " << from3 << std::hexfloat << " (" << from3 << ')' << std::defaultfloat << "\n和 " << to3 << std::hexfloat << " (" << to3 << ")\n" << std::defaultfloat << std::setprecision(20); std::cout << "\nnextafter与nexttoward的区别:\n"; long double dir = std::nextafter(from1, 1.0L); // 第一个次正规长双精度数 float x = std::nextafter(from1, dir); // 首先将dir转换为float,得到0 std::cout << "使用nextafter,0之后的下一个浮点数为 " << from1 << " 是 " << x << '\n'; x = std::nexttoward(from1, dir); std::cout << "使用nexttoward,0之后的下一个浮点数为 " << from1 << " 是 " << x << '\n'; std::cout << "\n特殊值:\n"; { // #pragma STDC FENV_ACCESS ON std::feclearexcept(FE_ALL_EXCEPT); double from4 = DBL_MAX, to4 = std::nextafter(from4, INFINITY); std::cout << "DBL_MAX之后可表示的下一个双精度数为 " << std::setprecision(6) << from4 << std::hexfloat << " (" << from4 << ')' << std::defaultfloat << " 是 " << to4 << std::hexfloat << " (" << to4 << ")\n" << std::defaultfloat; if (std::fetestexcept(FE_OVERFLOW)) std::cout << " 触发了FE_OVERFLOW\n"; if (std::fetestexcept(FE_INEXACT)) std::cout << " 触发了FE_INEXACT\n"; } // FENV_ACCESS块结束 float from5 = 0
参见
|
C 文档
关于
nextafter
|