Namespaces
Variants

std:: nextafter, std:: nextafterf, std:: nextafterl, std:: nexttoward, std:: nexttowardf, std:: nexttowardl

From cppreference.net
Common mathematical functions
Nearest integer floating point operations
(C++11)
(C++11)
(C++11) (C++11) (C++11)
Floating point manipulation functions
(C++11) (C++11)
(C++11)
(C++11)
nextafter nexttoward
(C++11) (C++11)
(C++11)
Classification and comparison
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Types
(C++11)
(C++11)
(C++11)
Macro constants
定义于头文件 <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 起)
(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 ) ;

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 起)
(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 */

nextafter ( Arithmetic1 from, Arithmetic2 to ) ;
(A) (C++11 起)
(C++23 起 constexpr)
template < class Integer >
double nexttoward ( Integer from, long double to ) ;
(B) (C++11 起)
(C++23 起 constexpr)

返回 from 在朝向 to 方向上的下一个可表示值。

1-3) from 等于 to ,则返回 to 标准库为所有无 cv 限定的浮点类型提供 std::nextafter 的重载,将参数 from to 的类型作为浮点类型。 (C++23 起)
4-6) from 等于 to ,则返回转换为函数返回类型的 to (从 long double 转换时不会丢失范围或精度)。

标准库为所有无 cv 限定的浮点类型提供了 std::nexttoward 的重载,作为参数 from 的类型。然而,若对应 from 的实参具有 扩展浮点类型 ,则调用 std::nexttoward 非良构,因为无法保证下一个可表示值(或 to )能以 long double 表示。

(since C++23)
A) 为所有其他算术类型组合提供了额外的 std::nextafter 重载。
B) 为所有整数类型提供了额外的 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 满足:

  • num1 num2 具有类型 long double ,则 std :: nextafter ( num1, num2 ) 的效果等同于 std :: nextafter ( static_cast < long double > ( num1 ) ,
    static_cast < long double > ( num2 ) )
  • 否则,若 num1 和/或 num2 具有类型 double 或整数类型,则 std :: nextafter ( num1, num2 ) 的效果等同于 std :: nextafter ( static_cast < double > ( num1 ) ,
    static_cast < double > ( num2 ) )
  • 否则,若 num1 num2 具有类型 float ,则 std :: nextafter ( num1, num2 ) 的效果等同于 std :: nextafter ( static_cast < float > ( num1 ) ,
    static_cast < float > ( num2 ) )
(C++23 前)

num1 num2 具有算术类型,则 std :: nextafter ( num1, num2 ) 的效果等同于 std :: nextafter ( static_cast < /*common-floating-point-type*/ > ( num1 ) ,
static_cast < /*common-floating-point-type*/ > ( num2 ) )
,其中 /*common-floating-point-type*/ 是在 num1 num2 的类型之间具有最高 浮点转换等级 和最高 浮点转换子等级 的浮点类型,整数类型的实参被认为具有与 double 相同的浮点转换等级。

若不存在具有最高等级和子等级的此类浮点类型,则 重载决议 不会从提供的重载中得到可用候选。

(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