C++ 参考手册

位置:首页 > C++ 参考手册 >数值库 >常用数学函数 > std::nextafter, std::nextafterf, std::nextafterl, std::nexttoward, std::nexttowardf, std::nexttowardl

定义于头文件 <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 起)

返回 fromto 方向的下个可表示值。

1-3)from 等于 to ,则返回 to
5-7)from 等于 to ,则返回从 long double 转换到函数返回类型的 to ,而不带范围或精度的损失。
4) 所有 (1-3) 所不覆盖的算术类型参数的重载集或函数模板。若任何参数拥有整数类型,则将它转型为 double 。若任何参数为 long double ,则返回类型 Promoted 亦为 long double ,否则返回类型始终为 double
8) 接受任何整数类型 from 参数的重载集或函数模板。等价于 (6) (将参数转型为 double )。

参数

from, to - 浮点值

返回值

若不出现错误,则返回 fromto 的方向的下个可表示值。若 from 等于 to ,则返回 to ,转换到函数的类型。

若出现上溢所致的值域错误,则返回 ±HUGE_VAL±HUGE_VALF±HUGE_VALL (所带符号同 from )。

若出现下溢所致的值域错误,则返回正确结果。

错误处理

报告 math_errhandling 中指定的错误。

若实现支持 IEEE 浮点算术( IEC 60559 ),则

  • from 有限,但期待的结果无限,则引发 FE_INEXACTFE_OVERFLOW
  • from 不等于 to 且结果为非正规或零,则引发 FE_INEXACTFE_UNDERFLOW
  • 任何情况下,返回值独立于当前舍入模式。
  • fromto 为 NaN ,则返回 NaN

注意

POSIX 指定上溢和下溢条件是值域错误(可以设置 errno )。

IEC 60559 推荐凡在 from==to 时返回 from 。这些函数替而返回 to ,这使得围绕零的行为一致: std::nextafter(-0.0, +0.0) 返回 +0.0std::nextafter(+0.0, -0.0) 返回 –0.0

示例

#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

参阅