Spec-Zone.ru › C

nextafter, nextafterf, nextafterl, nexttoward, nexttowardf, nexttowardl

Определено в заголовке <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) Сначала оба аргумента преобразуются к типу функции, затем возвращается следующее представимое значение from в направлении to. Если from равно to, возвращается to.
4-6) Сначала первый аргумент преобразуется к типу функции, затем возвращается следующее представимое значение from в направлении to. Если from равно to, возвращается to, преобразованное из long double в тип возвращаемого значения функции без потери диапазона или точности.
7) Универсальный макрос типа: Если какой-либо аргумент имеет тип long double, вызывается nextafterl. В противном случае, если какой-либо аргумент имеет целочисленный тип или тип double, вызывается nextafter. В противном случае вызывается nextafterf.
8) Универсальный макрос типа: Если аргумент from имеет тип long double, вызывается nexttowardl. В противном случае, если from имеет целочисленный тип или тип double, вызывается nexttoward. В противном случае вызывается nexttowardf.

Параметры

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 всякий раз, когда from == to. Эти функции возвращают to вместо этого, что делает поведение около нуля согласованным: nextafter(-0.0, +0.0) возвращает +0.0, а nextafter(+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);
 
    // 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)

Ссылки

  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.12.11.3 Функции nextafter (с. 187)
    • 7.12.11.4 Функции nexttoward (с. 187)
    • 7.25 Универсальные математические функции <tgmath.h> (с. 272-273)
    • F.10.8.3 Функции nextafter (с. 386)
    • F.10.8.4 Функции nexttoward (с. 386)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.12.11.3 Функции nextafter (с. 256)
    • 7.12.11.4 Функции nexttoward (с. 257)
    • 7.25 Универсальные математические функции <tgmath.h> (с. 373-375)
    • F.10.8.3 Функции nextafter (с. 529)
    • F.10.8.4 Функции nexttoward (с. 529)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.12.11.3 Функции nextafter (с. 237)
    • 7.12.11.4 Функции nexttoward (с. 238)
    • 7.22 Универсальные математические функции <tgmath.h> (с. 335-337)
    • F.9.8.3 Функции nextafter (с. 466)
    • F.9.8.4 Функции nexttoward (с. 466)

См. также

Документация C++ для nextafter

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/numeric/math/nextafter

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API