Namespaces
Variants

Type-generic math (since C99)

From cppreference.net

El encabezado <tgmath.h> incluye los encabezados <math.h> y <complex.h> y define varias macros genéricas de tipo que determinan qué función real o, cuando es aplicable, función compleja llamar basándose en los tipos de los argumentos.

Para cada macro, los parámetros cuyo tipo real correspondiente en la función sin sufijo <math.h> es double se conocen como parámetros genéricos (por ejemplo, ambos parámetros de pow son parámetros genéricos, pero solo el primer parámetro de scalbn es un parámetro genérico).

Cuando se utiliza una macro de <tgmath.h> , los tipos de los argumentos pasados a los parámetros genéricos determinan qué función es seleccionada por la macro como se describe a continuación. Si los tipos de los argumentos no son compatibles con los tipos de parámetros de la función seleccionada, el comportamiento es indefinido (por ejemplo, si se pasa un argumento complejo a una macro de <tgmath.h> que solo admite reales: float complex fc ; ceil ( fc ) ; o double complex dc ; double d ; fmax ( dc, d ) ; son ejemplos de comportamiento indefinido).

Nota: las macros genéricas de tipo se implementaron de manera definida por la implementación en C99, pero la palabra clave de C11 _Generic hace posible implementar estas macros de manera portable.

Contenidos

Macros genéricas para tipos complejos/reales

Para todas las funciones que tienen contrapartes tanto reales como complejas, existe una macro genérica de tipo XXX , que llama a cualquiera de:

  • función real:
  • float variante XXXf
  • double variante XXX
  • long double variante XXXl
  • función compleja:
  • float variante cXXXf
  • double variante cXXX
  • long double variante cXXXl

Una excepción a la regla anterior es la macro fabs (consulte la tabla a continuación).

La función a llamar se determina de la siguiente manera:

  • Si alguno de los argumentos para los parámetros genéricos es imaginario, el comportamiento se especifica en cada página de referencia de función individualmente (en particular, sin , cos , tan , cosh , sinh , tanh , asin , atan , asinh , y atanh llaman a funciones reales , los tipos de retorno de sin , tan , sinh , tanh , asin , atan , asinh , y atanh son imaginarios, y los tipos de retorno de cos y cosh son reales).
  • Si alguno de los argumentos para los parámetros genéricos es complejo, entonces se llama a la función compleja, de lo contrario se llama a la función real.
  • Si alguno de los argumentos para los parámetros genéricos es long double , entonces se llama a la variante long double . De lo contrario, si alguno de los parámetros es double o entero, entonces se llama a la variante double . De lo contrario, se llama a la variante float .

Las macros genéricas de tipo son las siguientes:

Macro genérico de tipos
macro
Variantes de función
real
Variantes de función
compleja
float double long double float double long double
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
seno 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

Funciones solo reales

Para todas las funciones que no tienen contrapartes complejas, con excepción de modf , existe una macro genérica de tipo XXX , que llama a cualquiera de las variantes de una función real:

  • float variante XXXf
  • double variante XXX
  • long double variante XXXl

La función a llamar se determina de la siguiente manera:

  • Si alguno de los argumentos para los parámetros genéricos es long double , entonces se llama a la variante long double . De lo contrario, si alguno de los argumentos para los parámetros genéricos es double , entonces se llama a la variante double . De lo contrario, se llama a la variante float .
Macro genérico de tipos
macro
Variantes de función
real
float double long double
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
resto 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

Funciones exclusivas de números complejos

Para todas las funciones de números complejos que no tienen equivalentes reales, existe una macro genérica de tipo cXXX , que llama a cualquiera de las variantes de una función compleja:

La función a llamar se determina de la siguiente manera:

  • Si alguno de los argumentos para los parámetros genéricos es real, complejo o imaginario, entonces se llama a la función compleja apropiada.
Macro genérico de tipo
macro
Variantes de funciones
complejas
float double long double
carg cargf carg cargl
conj conjf conj conjl
creal crealf creal creall
cimag cimagf cimag cimagl
cproj cprojf cproj cprojl

Ejemplo

#include <stdio.h>
#include <tgmath.h>
int main(void)
{
    int i = 2;
    printf("sqrt(2) = %f\n", sqrt(i)); // el tipo de argumento es int, llama a sqrt
    float f = 0.5;
    printf("sin(0.5f) = %f\n", sin(f)); // el tipo de argumento es float, llama a sinf
    float complex dc = 1 + 0.5*I;
    float complex z = sqrt(dc); // el tipo de argumento es float complex, llama a csqrtf
    printf("sqrt(1 + 0.5i) = %f+%fi\n",
           creal(z),  // el tipo de argumento es float complex, llama a crealf
           cimag(z)); // el tipo de argumento es float complex, llama a cimagf
}

Salida:

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

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 7.25 Matemáticas genéricas de tipos <tgmath.h> (p: TBD)
  • Estándar C17 (ISO/IEC 9899:2018):
  • 7.25 Matemáticas genéricas de tipos <tgmath.h> (p: 272-273)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 7.25 Matemáticas genéricas de tipos <tgmath.h> (p: 373-375)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 7.22 Matemáticas genéricas de tipos <tgmath.h> (p: 335-337)