Spec-Zone.ru › C

round, roundf, roundl, lround, lroundf, lroundl, llround, llroundf, llroundl

Определён в заголовочном файле <math.h>
float       roundf( float arg );
(1) (начиная с C99)
double      round( double arg );
(2) (начиная с C99)
long double roundl( long double arg );
(3) (начиная с C99)
Определён в заголовочном файле <tgmath.h>
#define round( arg )
(4) (начиная с C99)
Определён в заголовочном файле <math.h>
long      lroundf( float arg );
(5) (начиная с C99)
long      lround( double arg );
(6) (начиная с C99)
long      lroundl( long double arg );
(7) (начиная с C99)
Определён в заголовочном файле <tgmath.h>
#define lround( arg )
(8) (начиная с C99)
Определён в заголовочном файле <math.h>
long long llroundf( float arg );
(9) (начиная с C99)
long long llround( double arg );
(10) (начиная с C99)
long long llroundl( long double arg );
(11) (начиная с C99)
Определён в заголовочном файле <tgmath.h>
#define llround( arg )
(12) (начиная с C99)
1-3) Вычисляет ближайшее целое значение к arg (в формате с плавающей точкой), округляя случаи ровно посередине от нуля независимо от текущего режима округления.
5-7, 9-11) Вычисляет ближайшее целое значение к arg (в целочисленном формате), округляя случаи ровно посередине от нуля независимо от текущего режима округления.
4,8,12) Обобщённые по типу макросы: если arg имеет тип longdouble, вызывается roundl, lroundl, llroundl. В противном случае, если arg имеет целочисленный тип или тип double, вызывается round, lround, llround. В противном случае вызывается соответственно roundf, lroundf, llroundf.

Параметры

arg - значение с плавающей точкой

Возвращаемое значение

Если ошибки не возникают, возвращается ближайшее целое значение к arg, округлённое в случаях ровно посередине от нуля.

Возвращаемое значение
Аргумент

Если возникает ошибка области определения, возвращается значение, определяемое реализацией.

Обработка ошибок

Об ошибках сообщается в соответствии с указаниями в math_errhandling.

Если результат lround или llround выходит за пределы диапазона, представимого возвращаемым типом, может возникнуть ошибка области определения или ошибка диапазона.

Если реализация поддерживает арифметику с плавающей точкой IEEE (IEC 60559):

Для функции round, roundf и roundl:
  • Текущий режим округления не влияет на результат.
  • Если arg равно ±∞, оно возвращается без изменений.
  • Если arg равно ±0, оно возвращается без изменений.
  • Если arg — NaN, возвращается NaN.
Для семейств функций lround и llround:
  • FE_INEXACT никогда не возникает.
  • Текущий режим округления не влияет на результат.
  • Если arg равно ±∞, возникает FE_INVALID и возвращается значение, определяемое реализацией.
  • Если результат округления выходит за пределы диапазона возвращаемого типа, возникает FE_INVALID и возвращается значение, определяемое реализацией.
  • Если arg — NaN, возникает FE_INVALID и возвращается значение, определяемое реализацией.

Примечания

При округлении конечного нецелого значения функция round может (но не обязана) вызвать FE_INEXACT.

Наибольшие представимые значения с плавающей точкой являются точными целыми во всех стандартных форматах с плавающей точкой, поэтому round сама по себе никогда не приводит к переполнению; однако результат может переполнить любой целочисленный тип (включая intmax_t) при сохранении в целочисленной переменной.

В спецификации POSIX указано, что во всех случаях, когда lround или llround вызывают FE_INVALID, возникают ошибки области определения.

Версия round для типа double ведёт себя так, как если бы она была реализована следующим образом:

#include <math.h>
#pragma STDC FENV_ACCESS ON

double round(double x)
{
    return signbit(x) ? ceil(x - 0.5) : floor(x + 0.5);
}

Пример

#include <assert.h>
#include <fenv.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
// #pragma STDC FENV_ACCESS ON

double custom_round(double x)
{
    return signbit(x) ? ceil(x - 0.5) : floor(x + 0.5);
}

void test_custom_round()
{
    const double sample[] =
    {
        0.0, 2.3, 2.5 - DBL_EPSILON, 2.5, 2.5 + DBL_EPSILON, 2.7, INFINITY
    };
    for (size_t t = 0; t < sizeof sample / sizeof(double); ++t)
        assert(round(+sample[t]) == custom_round(+sample[t]) &&
               round(-sample[t]) == custom_round(-sample[t]));
}

int main(void)
{
    // round
    printf("round(+2.3) = %+.1f  ", round(2.3));
    printf("round(+2.5) = %+.1f  ", round(2.5));
    printf("round(+2.7) = %+.1f\n", round(2.7));
    printf("round(-2.3) = %+.1f  ", round(-2.3));
    printf("round(-2.5) = %+.1f  ", round(-2.5));
    printf("round(-2.7) = %+.1f\n", round(-2.7));

    printf("round(-0.0) = %+.1f\n", round(-0.0));
    printf("round(-Inf) = %+f\n",   round(-INFINITY));

    test_custom_round();

    // lround
    printf("lround(+2.3) = %+ld  ", lround(2.3));
    printf("lround(+2.5) = %+ld  ", lround(2.5));
    printf("lround(+2.7) = %+ld\n", lround(2.7));
    printf("lround(-2.3) = %+ld  ", lround(-2.3));
    printf("lround(-2.5) = %+ld  ", lround(-2.5));
    printf("lround(-2.7) = %+ld\n", lround(-2.7));

    printf("lround(-0.0) = %+ld\n", lround(-0.0));
    printf("lround(-Inf) = %+ld\n", lround(-INFINITY)); // FE_INVALID raised

    // error handling
    feclearexcept(FE_ALL_EXCEPT);
    printf("lround(LONG_MAX+1.5) = %ld\n", lround(LONG_MAX + 1.5));
    if (fetestexcept(FE_INVALID))
        puts("    FE_INVALID was raised");
}

Возможный вывод:

round(+2.3) = +2.0  round(+2.5) = +3.0  round(+2.7) = +3.0
round(-2.3) = -2.0  round(-2.5) = -3.0  round(-2.7) = -3.0
round(-0.0) = -0.0
round(-Inf) = -inf
lround(+2.3) = +2  lround(+2.5) = +3  lround(+2.7) = +3
lround(-2.3) = -2  lround(-2.5) = -3  lround(-2.7) = -3
lround(-0.0) = +0
lround(-Inf) = -9223372036854775808
lround(LONG_MAX+1.5) = -9223372036854775808
    FE_INVALID was raised

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 7.12.9.6 Функции round (стр.: уточняется)
    • 7.12.9.7 Функции lround и llround (стр.: уточняется)
    • 7.25 Обобщённая по типу математика <tgmath.h> (стр.: уточняется)
    • F.10.6.6 Функции round (стр.: уточняется)
    • F.10.6.7 Функции lround и llround (стр.: уточняется)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.12.9.6 Функции round (стр.: 184)
    • 7.12.9.7 Функции lround и llround (стр.: 184-185)
    • 7.25 Обобщённая по типу математика <tgmath.h> (стр.: 272-273)
    • F.10.6.6 Функции round (стр.: 384)
    • F.10.6.7 Функции lround и llround (стр.: 385)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.12.9.6 Функции round (стр.: 253)
    • 7.12.9.7 Функции lround и llround (стр.: 253)
    • 7.25 Обобщённая по типу математика <tgmath.h> (стр.: 373-375)
    • F.10.6.6 Функции round (стр.: 527)
    • F.10.6.7 Функции lround и llround (стр.: 528)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.12.9.6 Функции round (стр.: 233)
    • 7.12.9.7 Функции lround и llround (стр.: 234)
    • 7.22 Обобщённая по типу математика <tgmath.h> (стр.: 335-337)
    • F.9.6.6 Функции round (стр.: 464)
    • F.9.6.7 Функции lround и llround (стр.: 464)

См. также

floorfloorffloorl
(C99)(C99)
вычисляет наибольшее целое, не превосходящее заданное значение
(функция)
ceilceilfceill
(C99)(C99)
вычисляет наименьшее целое, не меньшее заданного значения
(функция)
trunctruncftruncl
(C99)(C99)(C99)
округляет до ближайшего целого, модуль которого не больше модуля заданного значения
(функция)
Документация C++ для round

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

Spec-Zone.ru

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