std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl
来自cppreference.com
定义于头文件 <cmath>
|
||
float nextafter ( float from, float to ); float nextafterf( float from, float to ); |
(1) | (C++11 起) |
double nextafter ( double from, double to ); |
(2) | (C++11 起) |
long double nextafter ( long double from, long double to ); long double nextafterl( long double from, long double to ); |
(3) | (C++11 起) |
Promoted nextafter ( Arithmetic1 from, Arithmetic2 to ); |
(4) | (C++11 起) |
float nexttoward ( float from, long double to ); float nexttowardf( float from, long double to ); |
(5) | (C++11 起) |
double nexttoward ( double from, long double to ); |
(6) | (C++11 起) |
long double nexttoward ( long double from, long double to ); long double nexttowardl( long double from, long double to ); |
(7) | (C++11 起) |
double nexttoward ( IntegralType from, long double to ); |
(8) | (C++11 起) |
返回 from
于 to
方向的下个可表示值。
1-3) 若
from
等于 to
,则返回 to
。5-7) 若
from
等于 to
,则返回从 long double 转换到函数返回类型的 to
,而不带范围或精度的损失。4) 所有 (1-3) 所不覆盖的算术类型参数的重载集或函数模板。若任何参数拥有整数类型,则将它转型为 double 。若任何参数为 long double ,则返回类型
Promoted
亦为 long double ,否则返回类型始终为 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
。
nextafter
常通过操纵 IEEE 表示实现( glibc )( musl )。
示例
运行此代码
#include <cmath> #include <iomanip> #include <iostream> #include <cfloat> #include <cfenv> 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); // nextafter 和 nexttoward 间的差异: long double dir = std::nextafter(from1, 1.0L); // 首个非正规 long double float x = nextafter(from1, dir); // 首先转换 dir 为 float ,给出 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'; // 特殊值 { #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"; } // 结束 FENV_ACCESS 块 float from5 = 0.0, to5 = std::nextafter(from5, -0.0); std::cout << "std::nextafter(+0.0, -0.0) gives " << std::fixed << to5 << '\n'; }
输出:
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) With nextafter, next float after 0 is 0 With nexttoward, next float after 0 is 1.4012984643248170709e-45 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