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 <fenv.h>
#include <float.h>
#include <math.h>
#include <stdio.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)

Литература

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 7.12.11.3 Функции nextafter (стр.: TBD)
    • 7.12.11.4 Функции nexttoward (стр.: TBD)
    • 7.25 Обобщённая математика по типам <tgmath.h> (стр.: TBD)
    • F.10.8.3 Функции nextafter (стр.: TBD)
    • F.10.8.4 Функции nexttoward (стр.: TBD)
  • Стандарт 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/c/numeric/math/nextafter

Spec-Zone.ru

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