nextafter, nextafterf, nextafterl, nexttoward, nexttowardf, nexttowardl

来自cppreference.com
< c‎ | numeric‎ | math
 
 
 
常用数学函数
函数
基本运算
(C99)
(C99)
(C99)
(C99)(C99)(C99)(C23)
最大/最小运算
指数函数
(C23)
(C99)
(C99)
(C23)
(C23)
(C99)
(C99)(C23)
(C23)
(C23)
幂函数
(C99)
(C23)
(C23)
(C99)
(C23)
(C23)
三角及双曲函数
(C23)
(C23)
(C23)
(C23)
(C99)
(C99)
(C99)
误差及伽马函数
(C99)
(C99)
(C99)
(C99)
临近整数的浮点运算
(C99)(C99)(C99)
(C99)
(C99)(C99)(C99)
(C23)(C23)(C23)(C23)
浮点操作函数
(C99)(C99)
(C99)(C23)
(C99)
nextafternexttoward
(C99)(C99)
(C23)(C23)
窄化运算
(C23)
(C23)
(C23)
(C23)
(C23)
(C23)
量与量指数函数
十进制重编码函数
全序与载荷函数
分类
(C99)
(C99)
(C99)
(C23)
类型
宏常量
 
定义于头文件 <math.h>
float       nextafterf( float from, float to );
(1) (C99 起)
double      nextafter( double from, double to );
(2) (C99 起)
long double nextafterl( long double from, long double to );
(3) (C99 起)
float       nexttowardf( float from, long double to );
(4) (C99 起)
double      nexttoward( double from, long double to );
(5) (C99 起)
long double nexttowardl( long double from, long double to );
(6) (C99 起)
定义于头文件 <tgmath.h>
#define nextafter(from, to)
(7) (C99 起)
#define nexttoward(from, to)
(8) (C99 起)
1-3) 首先,转换两个参数为函数的类型,然后返回 fromto 方向的下个可表示值。若 from 等于 to ,则返回 to
4-6) 首先,转换两个参数为函数的类型,然后返回 fromto 方向的下个可表示值。若 from 等于 to ,则返回从 long double 转换到函数返回类型的 to ,而不带范围或精度的损失。
7) 泛型宏:若任何参数拥有 long double 类型,则调用 nextafterl 。否则,若任何参数拥有整数类型或 double 类型,则调用 nextafter 。否则调用 nextafterf
8) 泛型宏:若任何参数拥有 long double 类型,则调用 nexttowardl 。否则,若任何参数拥有整数类型或 double 类型,则调用 nexttoward 。否则调用 nexttowardf

参数

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 ,这使得围绕零的行为一致: nextafter(-0.0, +0.0) 返回 +0.0nextafter(+0.0, -0.0) 返回 –0.0

nextafter 常通过操纵 IEEE 表示实现( glibc )( musl )。

示例

#include <math.h>
#include <stdio.h>
#include <float.h>
#include <fenv.h>
 
int main(void)
{
    float from1 = 0, to1 = nextafterf(from1, 1);
    printf("The next representable float after %.2f is %.20g (%a)\n", from1, to1, to1);
 
    float from2 = 1, to2 = nextafterf(from2, 2);
    printf("The next representable float after %.2f is %.20f (%a)\n", from2, to2, to2);
 
    double from3 = nextafter(0.1, 0), to3 = 0.1;
    printf("The number 0.1 lies between two valid doubles:\n"
           "    %.56f (%a)\nand %.55f  (%a)\n", from3, from3, to3, to3);
 
    // nextafter 和 nexttoward 间的差异:
    long double dir = nextafterl(from1, 1); // 第一个非正规 long double
    float x = nextafterf(from1, dir); // 首先转换 dir 为 float ,给出 0
    printf("Using nextafter, next float after %.2f (%a) is %.20g (%a)\n",
           from1, from1, x, x);
    x = nexttowardf(from1, dir);
    printf("Using nexttoward, next float after %.2f (%a) is %.20g (%a)\n",
           from1, from1, x, x);
 
    // 特殊值
    {
        #pragma STDC FENV_ACCESS ON
        feclearexcept(FE_ALL_EXCEPT);
        double from4 = DBL_MAX, to4 = nextafter(from4, INFINITY);
        printf("The next representable double after %.2g (%a) is %.23f (%a)\n",
               from4, from4, to4, to4);
        if(fetestexcept(FE_OVERFLOW)) puts("   raised FE_OVERFLOW");
        if(fetestexcept(FE_INEXACT)) puts("   raised FE_INEXACT");
    } // 结束 FENV_ACCESS 块
 
    float from5 = 0.0, to5 = nextafter(from5, -0.0);
    printf("nextafter(+0.0, -0.0) gives %.2g (%a)\n", to5, to5);
}

输出:

The next representable float after 0.00 is 1.4012984643248170709e-45 (0x1p-149)
The next representable float after 1.00 is 1.00000011920928955078 (0x1.000002p+0)
The number 0.1 lies between two valid doubles:
    0.09999999999999999167332731531132594682276248931884765625 (0x1.9999999999999p-4)
and 0.1000000000000000055511151231257827021181583404541015625  (0x1.999999999999ap-4)
Using nextafter, next float after 0.00 (0x0p+0) is 0 (0x0p+0)
Using nexttoward, next float after 0.00 (0x0p+0) is 1.4012984643248170709e-45 (0x1p-149)
The next representable double after 1.8e+308 (0x1.fffffffffffffp+1023) is inf (inf)
   raised FE_OVERFLOW
   raised FE_INEXACT
nextafter(+0.0, -0.0) gives -0 (-0x0p+0)

引用

  • C17 标准(ISO/IEC 9899:2018):
  • 7.12.11.3 The nextafter functions (p: 187)
  • 7.12.11.4 The nexttoward functions (p: 187)
  • 7.25 Type-generic math <tgmath.h> (p: 272-273)
  • F.10.8.3 The nextafter functions (p: 386)
  • F.10.8.4 The nexttoward functions (p: 386)
  • C11 标准(ISO/IEC 9899:2011):
  • 7.12.11.3 The nextafter functions (p: 256)
  • 7.12.11.4 The nexttoward functions (p: 257)
  • 7.25 Type-generic math <tgmath.h> (p: 373-375)
  • F.10.8.3 The nextafter functions (p: 529)
  • F.10.8.4 The nexttoward functions (p: 529)
  • C99 标准(ISO/IEC 9899:1999):
  • 7.12.11.3 The nextafter functions (p: 237)
  • 7.12.11.4 The nexttoward functions (p: 238)
  • 7.22 Type-generic math <tgmath.h> (p: 335-337)
  • F.9.8.3 The nextafter functions (p: 466)
  • F.9.8.4 The nexttoward functions (p: 466)

参阅