C
数值 | Numerics

nexttowardf

nextafter, nextafterf, nextafterl, nexttoward, nexttowardf, nexttowardl

在头文件中定义
float nextafterf( float from, float to (1)(since C99)
double nextafter( double from, double to (2)(since C99)
long double nextafterl( long double from, long double to (3)(since C99)
float nexttowardf( float from, long double to (4)(since C99)
double nexttoward( double from, long double to (5)(since C99)
long double nexttowardl( long double from, long double to (6)(since C99)
Defined in header <tgmath.h>
#define nextafter(from, to)(7)(since C99)
#define nexttoward(from, to)(8)(since C99)

1-3)首先,将两个参数都转换为函数的类型,然后返回下一个可表示值from的方向to。如果from等于toto则返回。

4-6)首先,将第一个参数转换为函数的类型,然后返回下一个可表示值from的方向to。如果from等于toto则返回,转换long double为函数的返回类型,但不会丢失范围或精度。

7)类型 - 通用宏:如果任何参数具有类型long doublenextafterl则被调用。否则,如果任何参数具有整数类型或具有类型doublenextafter则被调用。否则,nextafterf被调用。

8)类型 - 通用宏:如果参数from具有类型long doublenexttowardl则被调用。否则,如果from有整数类型或类型doublenexttoward则调用。否则,nexttowardf被调用。

参数

from, to-浮点值

返回值

如果没有错误发生,下一个可表示值from的方向to。返回。如果from等于to,则to返回,转换为函数的类型。

如果范围误差由于发生溢出,±HUGE_VAL±HUGE_VALF,或±HUGE_VALL被返回(与相同的符号from)。

如果由于下溢而发生范围错误,则返回正确的结果。

错误处理

按照math_errhandling中的指定报告错误。

如果实现支持IEEE浮点运算(IEC 60559),

  • 如果from是有限的,但预期的结果是无穷大,提高FE_INEXACTFE_OVERFLOW

笔记

POSIX指定溢出和下溢条件是范围错误(可能会设置错误)。

IEC 60559建议from每当返回from==to。这些函数会返回to,这会使零之间的行为保持一致:nextafter(-0.0, +0.0)返回+0.0nextafter(+0.0, -0.0)返回–0.0

#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 // difference between nextafter and nexttoward: long double dir = nextafterl(from1, 1 // first subnormal long double float x = nextafterf(from1, dir // first converts dir to float, giving 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 // special values { #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" } // end FENV_ACCESS block 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)

参考

  • C11标准(ISO / IEC 9899:2011):