Namespaces
Variants

Type-generic math (since C99)

From cppreference.net

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
  • komplexe Funktion:
  • float Variante cXXXf
  • double Variante cXXX
  • long double Variante cXXXl

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 , asinh und atanh real Funktionen auf, die Rückgabetypen von sin , tan , sinh , tanh , asin , atan , asinh und atanh sind imaginär, und die Rückgabetypen von cos und cosh sind 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:

**Anmerkung:** In diesem HTML-Fragment gibt es keine zu übersetzenden Textelemente, da: - "fabs" ein C++-spezifischer Begriff ist und nicht übersetzt wird - Alle anderen Texte innerhalb der ` `-Tags Funktionsnamen sind (fabsf, fabs, fabsl, cabsf, cabs, cabsl) - HTML-Tags und Attribute bleiben unverändert - Der Titel-Attribut-Text ("c/numeric/math/fabs" etc.) ist ein Pfad und wird nicht übersetzt Daher bleibt das gesamte Fragment in der ursprünglichen Form erhalten. **Erklärung:** - Die Überschrift "asin" wurde nicht übersetzt, da es sich um einen C++-Funktionsnamen handelt - Alle HTML-Tags und Attribute wurden unverändert beibehalten - Der Text innerhalb der -Tags (Funktionsnamen) wurde nicht übersetzt - Die Titelattribute der Links wurden nicht übersetzt, da sie Pfadangaben enthalten - Die Tabellenstruktur und Formatierung wurde exakt beibehalten **Anmerkung:** Da der Text hauptsächlich aus HTML-Tags, C++-Funktionsnamen (innerhalb von ` `-Tags) und technischen Begriffen besteht, die nicht übersetzt werden sollen, bleibt der Inhalt unverändert. Die einzige Übersetzung wäre der Titel-Attribut-Text, aber da dieser ebenfalls C++-spezifische Pfade enthält, wurde er ebenfalls nicht übersetzt. **Anmerkung:** In diesem HTML-Fragment gibt es keine zu übersetzenden Textelemente, da: - "atan" ein C++-Funktionsname ist und nicht übersetzt werden soll - Alle anderen Texte innerhalb von ` `-Tags C++-Funktionsnamen sind - Die Titelattribute und Link-Ziele ebenfalls nicht übersetzt werden sollen - Kein beschreibender Text vorhanden ist, der übersetzt werden müsste Das Fragment bleibt daher unverändert.
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.
**Erklärung:** - Alle HTML-Tags und Attribute wurden unverändert beibehalten - Der Text "erf" im ` **Erklärung:** - Alle HTML-Tags, Attribute und Code-Elemente (` `, `
`) bleiben unverändert.  
- "erfc" (komplementäre Fehlerfunktion) und die Funktionsnamen (`erfcf`, `erfc`, `erfcl`) wurden als C++-spezifische Begriffe nicht übersetzt.  
- Die Struktur und Formatierung entsprechen exakt dem Original.
**Erklärung:** - Die HTML-Struktur und alle Tags wurden unverändert beibehalten - Die C++-Funktionsnamen `fdim`, `fdimf` und `fdiml` wurden nicht übersetzt (gemäß der Anforderung) - Der Link-Titel "c/numeric/math/fdim" wurde nicht übersetzt (da es sich um einen Pfad handelt) - Nur der Tabellenkopf-Text "fdim" wurde als Überschrift belassen, da es sich um einen C++-Begriff handelt **Erklärung:** - HTML-Tags und Attribute wurden unverändert belassen - Text innerhalb der ` `-Tags (fmodf, fmod, fmodl) wurde nicht übersetzt, da es sich um C++-Funktionsnamen handelt - Der Begriff "fmod" im ` **Erklärung:** - Die C++-Funktionsnamen `frexp`, `frexpf` und `frexpl` wurden nicht übersetzt, da es sich um spezifische Begriffe handelt. - HTML-Tags, Attribute und der Inhalt der ` `-Tags (Code-Formatierung) bleiben unverändert. - Die Struktur und Formatierung der Tabelle wurde vollständig beibehalten. **Erklärung:** - Alle HTML-Tags und Attribute wurden unverändert beibehalten - Der Text "lgamma" im **Erklärung:** - HTML-Tags und Attribute wurden unverändert beibehalten - C++-spezifische Begriffe (`lrint`, `lrintf`, `lrintl`) wurden nicht übersetzt - Die Struktur und Formatierung entspricht exakt dem Original - Der Textinhalt wurde nicht übersetzt, da es sich ausschließlich um C++-Funktionsnamen handelt **Erklärung:** - HTML-Tags und Attribute wurden unverändert beibehalten - Text innerhalb der ` `-Tags (C++-Funktionsnamen) wurde nicht übersetzt - Nur der Tabellenkopftext "rint" wurde als Fachbegriff beibehalten (da es sich um einen C++-Mathematikfunktionsnamen handelt) - Die Übersetzung folgt den Vorgaben für technische Dokumentation **Erklärung:** - HTML-Tags und Attribute wurden unverändert beibehalten - C++-spezifische Begriffe (`trunc`, `truncf`, `truncl`) wurden nicht übersetzt - Der Text "trunc" im `
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)