Type-generic math (since C99)
Der Header <tgmath.h> inkludiert die Header <math.h> und <complex.h> und definiert mehrere typengenerische Makros , die basierend auf den Typen der Argumente bestimmen, welche reelle oder, falls zutreffend, komplexe Funktion aufgerufen werden soll.
Für jedes Makro sind die Parameter, deren entsprechender echter Typ in der unsuffigierten <math.h> Funktion double ist, als generische Parameter bekannt (zum Beispiel sind beide Parameter von pow generische Parameter, aber nur der erste Parameter von scalbn ist ein generischer Parameter).
Wenn ein <tgmath.h> -Makro verwendet wird, bestimmen die Typen der an die generischen Parameter übergebenen Argumente, welche Funktion durch das Makro ausgewählt wird, wie unten beschrieben. Wenn die Typen der Argumente nicht kompatibel mit den Parametertypen der ausgewählten Funktion sind, ist das Verhalten undefiniert (z.B. wenn ein komplexes Argument an ein nur für reelle Zahlen vorgesehenes <tgmath.h> -Makro übergeben wird: float complex fc ; ceil ( fc ) ; oder double complex dc ; double d ; fmax ( dc, d ) ; sind Beispiele für undefiniertes Verhalten).
Hinweis: Typgenerische Makros wurden in C99 auf implementationsdefinierte Weise implementiert, aber das C11-Schlüsselwort _Generic ermöglicht die Implementierung dieser Makros auf portable Weise.
Inhaltsverzeichnis |
Komplexe/reale typgenerische Makros
Für alle Funktionen, die sowohl reelle als auch komplexe Gegenstücke haben, existiert ein typengenerisches Makro
XXX
, das eine der folgenden Funktionen aufruft:
- reale Funktion:
-
-
float
Variante
XXXf -
double
Variante
XXX -
long
double
Variante
XXXl
-
float
Variante
- komplexe Funktion:
-
-
float
Variante
cXXXf -
double
Variante
cXXX -
long
double
Variante
cXXXl
-
float
Variante
Eine Ausnahme von der obigen Regel ist das
fabs
Makro (siehe die Tabelle unten).
Die aufzurufende Funktion wird wie folgt bestimmt:
-
Wenn eines der Argumente für die generischen Parameter imaginär ist, wird das Verhalten auf jeder Funktionsreferenzseite individuell spezifiziert (insbesondere rufen
sin,cos,tan,cosh,sinh,tanh,asin,atan,asinhundatanhreal Funktionen auf, die Rückgabetypen vonsin,tan,sinh,tanh,asin,atan,asinhundatanhsind imaginär, und die Rückgabetypen voncosundcoshsind reell). - Wenn eines der Argumente für die generischen Parameter komplex ist, wird die komplexe Funktion aufgerufen, andernfalls wird die reelle Funktion aufgerufen.
- Wenn eines der Argumente für die generischen Parameter long double ist, wird die long double Variante aufgerufen. Andernfalls, wenn einer der Parameter double oder ganzzahlig ist, wird die double Variante aufgerufen. Andernfalls wird die float Variante aufgerufen.
Die typgenerischen Makros sind wie folgt:
|
Typgenerisch
Makro |
Reelle Funktions-
varianten |
Komplexe Funktions-
varianten |
||||
|---|---|---|---|---|---|---|
| float | double | long double | float | double | long double | |
| fabs | fabsf | fabs | fabsl | cabsf | cabs | cabsl |
| exp | expf | exp | expl | cexpf | cexp | cexpl |
| Logarithmus | logf | log | logl | clogf | clog | clogl |
| pow | powf | pow | powl | cpowf | cpow | cpowl |
| Quadratwurzel | sqrtf | sqrt | sqrtl | csqrtf | csqrt | csqrtl |
| sin | sinf | sin | sinl | csinf | csin | csinl |
| Kosinus | cosf | cos | cosl | ccosf | ccos | ccosl |
| Tangens | 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 |
Nur-reelle Funktionen
Für alle Funktionen, die keine komplexen Gegenstücke haben, mit Ausnahme von
modf
, existiert ein typgenerisches Makro
XXX
, das entweder der Varianten einer reellen Funktion aufruft:
-
float
Variante
XXXf -
double
Variante
XXX -
long
double
Variante
XXXl
Die aufzurufende Funktion wird wie folgt bestimmt:
- Wenn eines der Argumente für die generischen Parameter long double ist, wird die long double -Variante aufgerufen. Andernfalls, wenn eines der Argumente für die generischen Parameter double ist, wird die double -Variante aufgerufen. Andernfalls wird die float -Variante aufgerufen.
|
Typgenerisch
Makro |
Reale Funktions-
varianten |
||
|---|---|---|---|
| float | double | long double | |
| atan2 | atan2f | atan2 | atan2l |
| cbrt | cbrtf | cbrt | cbrtl |
| ceil | ceilf | ceil | ceill |
| copysign | copysignf | copysign | copysignl |
| erf | erff | erf | erfl | `-Element wurde nicht übersetzt, da es sich um einen C++-spezifischen Begriff (Error Function) handelt - Die Funktionsnamen "erff", "erf" und "erfl" in den ` `-Tags wurden ebenfalls nicht übersetzt - Die Formatierung und Struktur der Tabelle bleibt vollständig erhalten |
| 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 | `-Tag wurde nicht übersetzt, da es sich um einen C++-spezifischen Term handelt - Die Formatierung und Struktur der Tabelle bleibt vollständig erhalten |
| frexp | frexpf | frexp | frexpl |
| hypot | hypotf | hypot | hypotl |
| ilogb | ilogbf | ilogb | ilogbl |
| ldexp | ldexpf | ldexp | ldexpl |
| lgamma | lgammaf | lgamma | lgammal | -Tag wurde nicht übersetzt, da es sich um einen C++-Funktionsnamen handelt - Die Funktionsnamen in -Tags (lgammaf, lgamma, lgammal) wurden ebenfalls nicht übersetzt - Die Formatierung und Struktur der Tabelle bleibt vollständig erhalten |
| 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 |
| Rest | remainderf | remainder | remainderl |
| remquo | remquof | remquo | remquol |
| rint | rintf | rint | rintl |
| Runde | roundf | round | roundl |
| scalbln | scalblnf | scalbln | scalblnl |
| scalbn | scalbnf | scalbn | scalbnl |
| tgamma | tgammaf | tgamma | tgammal |
| trunc | truncf | trunc | truncl | `-Element wurde nicht übersetzt, da es sich um einen C++-Funktionsnamen handelt - Die Formatierung und Struktur des HTML-Codes bleibt vollständig erhalten |
Nur für komplexe Zahlen Funktionen
Für alle komplexen Zahl-Funktionen, die keine realen Gegenstücke haben, existiert ein typgenerisches Makro
cXXX
, das entweder der Varianten einer komplexen Funktion aufruft:
Die aufzurufende Funktion wird wie folgt bestimmt:
- Wenn eines der Argumente für die generischen Parameter real, komplex oder imaginär ist, dann wird die entsprechende komplexe Funktion aufgerufen.
|
Typgenerische
Makros |
Varianten komplexer
Funktionen |
||
|---|---|---|---|
| float | double | long double | |
| carg | cargf | carg | cargl |
| conj | conjf | conj | conjl |
| creal | crealf | creal | creall |
| cimag | cimagf | cimag | cimagl |
| cproj | cprojf | cproj | cprojl |
Beispiel
#include <stdio.h> #include <tgmath.h> int main(void) { int i = 2; printf("sqrt(2) = %f\n", sqrt(i)); // Argumenttyp ist int, ruft sqrt auf float f = 0.5; printf("sin(0.5f) = %f\n", sin(f)); // Argumenttyp ist float, ruft sinf auf float complex dc = 1 + 0.5*I; float complex z = sqrt(dc); // Argumenttyp ist float complex, ruft csqrtf auf printf("sqrt(1 + 0.5i) = %f+%fi\n", creal(z), // Argumenttyp ist float complex, ruft crealf auf cimag(z)); // Argumenttyp ist float complex, ruft cimagf auf }
Ausgabe:
sqrt(2) = 1.414214 sin(0.5f) = 0.479426 sqrt(1 + 0.5i) = 1.029086+0.242934i
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 7.25 Typgenerische Mathematik <tgmath.h> (S: TBD)
- C17-Standard (ISO/IEC 9899:2018):
-
- 7.25 Typgenerische Mathematik <tgmath.h> (S: 272-273)
- C11-Standard (ISO/IEC 9899:2011):
-
- 7.25 Typgenerische Mathematik <tgmath.h> (S: 373-375)
- C99-Standard (ISO/IEC 9899:1999):
-
- 7.22 Typgenerische Mathematik <tgmath.h> (S: 335-337)