Type-generic math
الملف <tgmath.h> يتضمن الملفات <math.h> و <complex.h> ويعرف العديد من الماكرو عامة النوع التي تستدعي الدالة المناسبة للمعطى على حسب نوعا سواء كان حقيقيا أم مركبا.
كل ماكرو يأخذ معطى أو أكثر عام النوع generic parameter. المعطى عام النوع هو الذي نوعه double بالنسبة للدول الحقيقية المجردة (أي بدون حرف يدل على نوع المعطى) المعرفة في math.h. فمثلا كلا معطيا pow عام بينما فقط المعطى الأول من scalbn معطى عام.
When a <tgmath.h> macro is used the types of the arguments passed to the generic parameters determine which function is selected by the macro as described below. If the types of the arguments are not compatible with the parameter types of the selected function, the behavior is undefined (e.g. if a complex argument is passed into a real-only tgmath macro: float complex fc; ceil(fc) or double complex dc; double d; fmax(dc, d) are examples of undefined behavior)
Note: type-generic macros were implemented in implementation-defined manner in C99, but C11 keyword _Generic makes it possible to implement these macros in portable manner.
ماكرو عامة للمعطيات المركبة والحقيقية
For all functions that have both real and complex counterparts, a type-generic macro XXX exists, which calls either of:
- real function:
floatيؤدي إلى استدعاءXXXfdoubleيؤدي إلى استدعاءXXXlong doubleيؤدي إلى استدعاءXXXl
- complex function:
floatيؤدي إلى استدعاءcXXXfdoubleيؤدي إلى استدعاءcXXXlong doubleيؤدي إلى استدعاءcXXXl
An exception to the above rule is the fabs macro (see the table below).
تحديد الدالة المطلوبة يتم كالآتي:
- If any of the arguments for the generic parameters is imaginary, the behavior is specified on each function reference page individually (in particular, sin, cos, tag, cosh, sinh, tanh, asin, atan, asinh, and atanh call real functions, the return types of sin, tan, sinh, tanh, asin, atan, asinh, and atanh are imaginary, and the return types of cos and cosh are real)
- If any of the arguments for the generic parameters is complex, then the complex function is called, otherwise the real function is called.
- If any of the arguments for the generic parameters is
long double, then thelong doublevariant is called. Otherwise, if any of the parameters isdoubleor integer, then thedoublevariant is called. Otherwise,floatvariant is called.
The type-generic macros are as follows:
| ماكرو عام النوع | الدوال الحقيقية variants |
الدوال المركبة variants | ||||
|---|---|---|---|---|---|---|
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 |
| 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 |
دوال حقيقية فقط
For all functions that do not have complex counterparts, with the exception of modf, a type-generic macro XXX exists, which calls either of the variants of a real function:
floatيؤدي إلى استدعاءXXXfdoubleيؤدي إلى استدعاءXXXlong doubleيؤدي إلى استدعاءXXXl
تحديد الدالة المطلوبة يتم كالآتي:
- If any of the arguments for the generic parameters is
long double, then thelong doublevariant is called. Otherwise, if any of the arguments for the generic parameters isdouble, then thedoublevariant is called. Otherwise,floatvariant is called.
دوال مركبة فقط
لكل الدوال المركبة التي ليس لها نظير حقيقي, يوجد ماكرو عام النوع على الصورة cXXX.
يقوم هذا الماكرو بإستدعاء النظير المناسب على حسب المعطى:
float complexيؤدي إلى استدعاءcXXXfdouble complexيؤدي إلى استدعاءcXXXlong double complexيؤدي إلى استدعاءcXXXl
تحديد الدالة المطلوبة يتم كالآتي:
| ماكرو عام النوع | الدوال المركبة variants | ||
|---|---|---|---|
float |
double |
long double | |
| 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