Spec-Zone.ru › C

Математика с обобщением по типу (начиная с C99)

Заголовок <tgmath.h> включает заголовки <math.h> и <complex.h> и определяет несколько макросов с обобщением по типу, которые определяют, какую вещественную или, если применимо, комплексную функцию вызвать в зависимости от типов аргументов.

Для каждого макроса параметры, соответствующий вещественный тип которых в функции <math.h> без суффикса — double, называются обобщёнными параметрами (например, оба параметра pow являются обобщёнными, но только первый параметр scalbn является обобщённым).

При использовании макроса из <tgmath.h> типы аргументов, переданных обобщённым параметрам, определяют, какую функцию выберет макрос, как описано ниже. Если типы аргументов не совместимы с типами параметров выбранной функции, поведение не определено (например, если комплексный аргумент передан макросу из <tgmath.h>, предназначенному только для вещественных чисел: float complex fc; ceil(fc); или double complex dc; double d; fmax(dc, d); являются примерами неопределённого поведения).

Примечание: в C99 макросы с обобщением по типу реализовывались способом, определяемым реализацией, но ключевое слово C11 _Generic позволяет реализовать эти макросы переносимым способом.

Макросы с обобщением по типу для комплексных и вещественных чисел

Для всех функций, имеющих как вещественные, так и комплексные аналоги, существует макрос с обобщением по типу XXX, который вызывает одну из следующих функций:

  • вещественная функция:
    • вариант float XXXf
    • вариант double XXX
    • вариант longdouble XXXl
  • комплексная функция:
    • вариант float cXXXf
    • вариант double cXXX
    • вариант longdouble cXXXl

Исключением из приведённого выше правила является макрос fabs (см. таблицу ниже).

Вызываемая функция определяется следующим образом:

  • Если какой-либо аргумент обобщённого параметра является мнимым, поведение определяется отдельно на странице описания каждой функции (в частности, sin, cos, tag, cosh, sinh, tanh, asin, atan, asinh и atanh вызывают вещественные функции, возвращаемые типы sin, tan, sinh, tanh, asin, atan, asinh и atanh являются мнимыми, а возвращаемые типы cos и cosh — вещественными).
  • Если какой-либо аргумент обобщённого параметра является комплексным, вызывается комплексная функция, в противном случае — вещественная.
  • Если какой-либо аргумент обобщённого параметра имеет тип longdouble, вызывается вариант longdouble. В противном случае, если какой-либо параметр имеет тип double или является целым числом, вызывается вариант double. Иначе вызывается вариант float.

Макросы с обобщением по типу представлены ниже:

Макрос с обобщением
по типу
Варианты вещественных
функций
Варианты комплексных
функций
float double longdouble float double longdouble
fabs fabsf fabs fabsl cabsf cabs cabsl
exp expf exp expl cexpf cexp cexpl
log logf log logl clogf clog clogl
pow powf pow powl cpowf cpow cpowl
sqrt sqrtf sqrt sqrtl csqrtf csqrt csqrtl
sin sinf sin sinl csinf csin csinl
cos cosf cos cosl ccosf ccos ccosl
tan tanf tan tanl ctanf ctan ctanl
asin asinf asin asinl casinf casin casinl
acos acosf acos acosl cacosf cacos cacosl
atan atanf atan atanl catanf catan catanl
sinh sinhf sinh sinhl csinhf csinh csinhl
cosh coshf cosh coshl ccoshf ccosh ccoshl
tanh tanhf tanh tanhl ctanhf ctanh ctanhl
asinh asinhf asinh asinhl casinhf casinh casinhl
acosh acoshf acosh acoshl cacoshf cacosh cacoshl
atanh atanhf atanh atanhl catanhf catanh catanhl

Функции только для вещественных чисел

Для всех функций, не имеющих комплексных аналогов, за исключением modf, существует макрос с обобщением по типу XXX, который вызывает один из вариантов вещественной функции:

  • вариант float XXXf
  • вариант double XXX
  • вариант longdouble XXXl

Вызываемая функция определяется следующим образом:

  • Если какой-либо аргумент обобщённого параметра имеет тип longdouble, вызывается вариант longdouble. В противном случае, если какой-либо аргумент обобщённого параметра имеет тип double, вызывается вариант double. Иначе вызывается вариант float.
Макрос с обобщением
по типу
Варианты вещественных
функций
float double longdouble
atan2 atan2f atan2 atan2l
cbrt cbrtf cbrt cbrtl
ceil ceilf ceil ceill
copysign copysignf copysign copysignl
erf erff erf erfl
erfc erfcf erfc erfcl
exp2 exp2f exp2 exp2l
expm1 expm1f expm1 expm1l
fdim fdimf fdim fdiml
floor floorf floor floorl
fma fmaf fma fmal
fmax fmaxf fmax fmaxl
fmin fminf fmin fminl
fmod fmodf fmod fmodl
frexp frexpf frexp frexpl
hypot hypotf hypot hypotl
ilogb ilogbf ilogb ilogbl
ldexp ldexpf ldexp ldexpl
lgamma lgammaf lgamma lgammal
llrint llrintf llrint llrintl
llround llroundf llround llroundl
log10 log10f log10 log10l
log1p log1pf log1p log1pl
log2 log2f log2 log2l
logb logbf logb logbl
lrint lrintf lrint lrintl
lround lroundf lround lroundl
nearbyint nearbyintf nearbyint nearbyintl
nextafter nextafterf nextafter nextafterl
nexttoward nexttowardf nexttoward nexttowardl
remainder remainderf remainder remainderl
remquo remquof remquo remquol
rint rintf rint rintl
round roundf round roundl
scalbln scalblnf scalbln scalblnl
scalbn scalbnf scalbn scalbnl
tgamma tgammaf tgamma tgammal
trunc truncf trunc truncl

Функции только для комплексных чисел

Для всех функций комплексных чисел, не имеющих вещественных аналогов, существует макрос с обобщением по типу cXXX, который вызывает один из вариантов комплексной функции:

  • вариант floatcomplex cXXXf
  • вариант doublecomplex cXXX
  • вариант longdoublecomplex cXXXl

Вызываемая функция определяется следующим образом:

  • Если какой-либо аргумент обобщённого параметра является вещественным, комплексным или мнимым, вызывается соответствующая комплексная функция.
Макрос с обобщением
по типу
Варианты комплексных
функций
float double longdouble
carg cargf carg cargl
conj conjf conj conjl
creal crealf creal creall
cimag cimagf cimag cimagl
cproj cprojf cproj cprojl

Пример

#include <stdio.h>
#include <tgmath.h>

int main(void)
{
    int i = 2;
    printf("sqrt(2) = %f\n", sqrt(i)); // argument type is int, calls sqrt

    float f = 0.5;
    printf("sin(0.5f) = %f\n", sin(f)); // argument type is float, calls sinf

    float complex dc = 1 + 0.5*I;
    float complex z = sqrt(dc); // argument type is float complex, calls csqrtf
    printf("sqrt(1 + 0.5i) = %f+%fi\n",
           creal(z),  // argument type is float complex, calls crealf
           cimag(z)); // argument type is float complex, calls cimagf
}

Вывод:

sqrt(2) = 1.414214
sin(0.5f) = 0.479426
sqrt(1 + 0.5i) = 1.029086+0.242934i

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2024):
    • 7.25 Математика с обобщением по типу <tgmath.h> (стр.: уточняется)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 7.25 Математика с обобщением по типу <tgmath.h> (стр.: 272–273)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 7.25 Математика с обобщением по типу <tgmath.h> (стр.: 373–375)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 7.22 Математика с обобщением по типу <tgmath.h> (стр.: 335–337)

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

Spec-Zone.ru

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