tgmath.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #ifndef _TGMATH_H
  2. #define _TGMATH_H
  3. /*
  4. the return types are only correct with gcc (__GNUC__)
  5. otherwise they are long double or long double complex
  6. the long double version of a function is never chosen when
  7. sizeof(double) == sizeof(long double)
  8. (but the return type is set correctly with gcc)
  9. */
  10. #include <math.h>
  11. #include <complex.h>
  12. #define __IS_FP(x) (sizeof((x)+1ULL) == sizeof((x)+1.0f))
  13. #define __IS_CX(x) (__IS_FP(x) && sizeof(x) == sizeof((x)+I))
  14. #define __IS_REAL(x) (__IS_FP(x) && 2*sizeof(x) == sizeof((x)+I))
  15. #define __FLT(x) (__IS_REAL(x) && sizeof(x) == sizeof(float))
  16. #define __LDBL(x) (__IS_REAL(x) && sizeof(x) == sizeof(long double) && sizeof(long double) != sizeof(double))
  17. #define __FLTCX(x) (__IS_CX(x) && sizeof(x) == sizeof(float complex))
  18. #define __DBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(double complex))
  19. #define __LDBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
  20. /* return type */
  21. #ifdef __GNUC__
  22. /*
  23. the result must be casted to the right type
  24. (otherwise the result type is determined by the conversion
  25. rules applied to all the function return types so it is long
  26. double or long double complex except for integral functions)
  27. this cannot be done in c99, so the typeof gcc extension is
  28. used and that the type of ?: depends on wether an operand is
  29. a null pointer constant or not
  30. (in c11 _Generic can be used)
  31. the c arguments below must be integer constant expressions
  32. so they can be in null pointer constants
  33. (__IS_FP above was carefully chosen this way)
  34. */
  35. /* if c then t else void */
  36. #define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))
  37. /* if c then t1 else t2 */
  38. #define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))
  39. /* cast to double when x is integral, otherwise use typeof(x) */
  40. #define __RETCAST(x) ( \
  41. __type2(__IS_FP(x), __typeof__(x), double))
  42. /* 2 args case, should work for complex types (cpow) */
  43. #define __RETCAST_2(x, y) ( \
  44. __type2(__IS_FP(x) && __IS_FP(y), \
  45. __typeof__((x)+(y)), \
  46. __typeof__((x)+(y)+1.0)))
  47. /* 3 args case (fma only) */
  48. #define __RETCAST_3(x, y, z) ( \
  49. __type2(__IS_FP(x) && __IS_FP(y) && __IS_FP(z), \
  50. __typeof__((x)+(y)+(z)), \
  51. __typeof__((x)+(y)+(z)+1.0)))
  52. /* drop complex from the type of x */
  53. /* TODO: wrong when sizeof(long double)==sizeof(double) */
  54. #define __RETCAST_REAL(x) ( \
  55. __type2(__IS_FP(x) && sizeof((x)+I) == sizeof(float complex), float, \
  56. __type2(sizeof((x)+1.0+I) == sizeof(double complex), double, \
  57. long double)))
  58. /* add complex to the type of x */
  59. #define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))
  60. #else
  61. #define __RETCAST(x)
  62. #define __RETCAST_2(x, y)
  63. #define __RETCAST_3(x, y, z)
  64. #define __RETCAST_REAL(x)
  65. #define __RETCAST_CX(x)
  66. #endif
  67. /* function selection */
  68. #define __tg_real_nocast(fun, x) ( \
  69. __FLT(x) ? fun ## f (x) : \
  70. __LDBL(x) ? fun ## l (x) : \
  71. fun(x) )
  72. #define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))
  73. #define __tg_real_2_1(fun, x, y) (__RETCAST(x)( \
  74. __FLT(x) ? fun ## f (x, y) : \
  75. __LDBL(x) ? fun ## l (x, y) : \
  76. fun(x, y) ))
  77. #define __tg_real_2(fun, x, y) (__RETCAST_2(x, y)( \
  78. __FLT(x) && __FLT(y) ? fun ## f (x, y) : \
  79. __LDBL((x)+(y)) ? fun ## l (x, y) : \
  80. fun(x, y) ))
  81. #define __tg_complex(fun, x) (__RETCAST_CX(x)( \
  82. __FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
  83. __LDBLCX((x)+I) ? fun ## l (x) : \
  84. fun(x) ))
  85. #define __tg_complex_retreal(fun, x) (__RETCAST_REAL(x)( \
  86. __FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
  87. __LDBLCX((x)+I) ? fun ## l (x) : \
  88. fun(x) ))
  89. #define __tg_real_complex(fun, x) (__RETCAST(x)( \
  90. __FLTCX(x) ? c ## fun ## f (x) : \
  91. __DBLCX(x) ? c ## fun (x) : \
  92. __LDBLCX(x) ? c ## fun ## l (x) : \
  93. __FLT(x) ? fun ## f (x) : \
  94. __LDBL(x) ? fun ## l (x) : \
  95. fun(x) ))
  96. /* special cases */
  97. #define __tg_real_remquo(x, y, z) (__RETCAST_2(x, y)( \
  98. __FLT(x) && __FLT(y) ? remquof(x, y, z) : \
  99. __LDBL((x)+(y)) ? remquol(x, y, z) : \
  100. remquo(x, y, z) ))
  101. #define __tg_real_fma(x, y, z) (__RETCAST_3(x, y, z)( \
  102. __FLT(x) && __FLT(y) && __FLT(z) ? fmaf(x, y, z) : \
  103. __LDBL((x)+(y)+(z)) ? fmal(x, y, z) : \
  104. fma(x, y, z) ))
  105. #define __tg_real_complex_pow(x, y) (__RETCAST_2(x, y)( \
  106. __FLTCX((x)+(y)) && __IS_FP(x) && __IS_FP(y) ? cpowf(x, y) : \
  107. __FLTCX((x)+(y)) ? cpow(x, y) : \
  108. __DBLCX((x)+(y)) ? cpow(x, y) : \
  109. __LDBLCX((x)+(y)) ? cpowl(x, y) : \
  110. __FLT(x) && __FLT(y) ? powf(x, y) : \
  111. __LDBL((x)+(y)) ? powl(x, y) : \
  112. pow(x, y) ))
  113. #define __tg_real_complex_fabs(x) (__RETCAST_REAL(x)( \
  114. __FLTCX(x) ? cabsf(x) : \
  115. __DBLCX(x) ? cabs(x) : \
  116. __LDBLCX(x) ? cabsl(x) : \
  117. __FLT(x) ? fabsf(x) : \
  118. __LDBL(x) ? fabsl(x) : \
  119. fabs(x) ))
  120. /* suppress any macros in math.h or complex.h */
  121. #undef acos
  122. #undef acosh
  123. #undef asin
  124. #undef asinh
  125. #undef atan
  126. #undef atan2
  127. #undef atanh
  128. #undef carg
  129. #undef cbrt
  130. #undef ceil
  131. #undef cimag
  132. #undef conj
  133. #undef copysign
  134. #undef cos
  135. #undef cosh
  136. #undef cproj
  137. #undef creal
  138. #undef erf
  139. #undef erfc
  140. #undef exp
  141. #undef exp2
  142. #undef expm1
  143. #undef fabs
  144. #undef fdim
  145. #undef floor
  146. #undef fma
  147. #undef fmax
  148. #undef fmin
  149. #undef fmod
  150. #undef frexp
  151. #undef hypot
  152. #undef ilogb
  153. #undef ldexp
  154. #undef lgamma
  155. #undef llrint
  156. #undef llround
  157. #undef log
  158. #undef log10
  159. #undef log1p
  160. #undef log2
  161. #undef logb
  162. #undef lrint
  163. #undef lround
  164. #undef nearbyint
  165. #undef nextafter
  166. #undef nexttoward
  167. #undef pow
  168. #undef remainder
  169. #undef remquo
  170. #undef rint
  171. #undef round
  172. #undef scalbln
  173. #undef scalbn
  174. #undef sin
  175. #undef sinh
  176. #undef sqrt
  177. #undef tan
  178. #undef tanh
  179. #undef tgamma
  180. #undef trunc
  181. /* tg functions */
  182. #define acos(x) __tg_real_complex(acos, (x))
  183. #define acosh(x) __tg_real_complex(acosh, (x))
  184. #define asin(x) __tg_real_complex(asin, (x))
  185. #define asinh(x) __tg_real_complex(asinh, (x))
  186. #define atan(x) __tg_real_complex(atan, (x))
  187. #define atan2(x,y) __tg_real_2(atan2, (x), (y))
  188. #define atanh(x) __tg_real_complex(atanh, (x))
  189. #define carg(x) __tg_complex_retreal(carg, (x))
  190. #define cbrt(x) __tg_real(cbrt, (x))
  191. #define ceil(x) __tg_real(ceil, (x))
  192. #define cimag(x) __tg_complex_retreal(cimag, (x))
  193. #define conj(x) __tg_complex(conj, (x))
  194. #define copysign(x,y) __tg_real_2(copysign, (x), (y))
  195. #define cos(x) __tg_real_complex(cos, (x))
  196. #define cosh(x) __tg_real_complex(cosh, (x))
  197. #define cproj(x) __tg_complex(cproj, (x))
  198. #define creal(x) __tg_complex_retreal(creal, (x))
  199. #define erf(x) __tg_real(erf, (x))
  200. #define erfc(x) __tg_real(erfc, (x))
  201. #define exp(x) __tg_real_complex(exp, (x))
  202. #define exp2(x) __tg_real(exp2, (x))
  203. #define expm1(x) __tg_real(expm1, (x))
  204. #define fabs(x) __tg_real_complex_fabs(x)
  205. #define fdim(x,y) __tg_real_2(fdim, (x), (y))
  206. #define floor(x) __tg_real(floor, (x))
  207. #define fma(x,y,z) __tg_real_fma((x), (y), (z))
  208. #define fmax(x,y) __tg_real_2(fmax, (x), (y))
  209. #define fmin(x,y) __tg_real_2(fmin, (x), (y))
  210. #define fmod(x,y) __tg_real_2(fmod, (x), (y))
  211. #define frexp(x,y) __tg_real_2_1(frexp, (x), (y))
  212. #define hypot(x,y) __tg_real_2(hypot, (x), (y))
  213. #define ilogb(x) __tg_real_nocast(ilogb, (x))
  214. #define ldexp(x,y) __tg_real_2_1(ldexp, (x), (y))
  215. #define lgamma(x) __tg_real(lgamma, (x))
  216. #define llrint(x) __tg_real_nocast(llrint, (x))
  217. #define llround(x) __tg_real_nocast(llround, (x))
  218. #define log(x) __tg_real_complex(log, (x))
  219. #define log10(x) __tg_real(log10, (x))
  220. #define log1p(x) __tg_real(log1p, (x))
  221. #define log2(x) __tg_real(log2, (x))
  222. #define logb(x) __tg_real(logb, (x))
  223. #define lrint(x) __tg_real_nocast(lrint, (x))
  224. #define lround(x) __tg_real_nocast(lround, (x))
  225. #define nearbyint(x) __tg_real(nearbyint, (x))
  226. #define nextafter(x,y) __tg_real_2(nextafter, (x), (y))
  227. #define nexttoward(x,y) __tg_real_2(nexttoward, (x), (y))
  228. #define pow(x,y) __tg_real_complex_pow((x), (y))
  229. #define remainder(x,y) __tg_real_2(remainder, (x), (y))
  230. #define remquo(x,y,z) __tg_real_remquo((x), (y), (z))
  231. #define rint(x) __tg_real(rint, (x))
  232. #define round(x) __tg_real(round, (x))
  233. #define scalbln(x,y) __tg_real_2_1(scalbln, (x), (y))
  234. #define scalbn(x,y) __tg_real_2_1(scalbn, (x), (y))
  235. #define sin(x) __tg_real_complex(sin, (x))
  236. #define sinh(x) __tg_real_complex(sinh, (x))
  237. #define sqrt(x) __tg_real_complex(sqrt, (x))
  238. #define tan(x) __tg_real_complex(tan, (x))
  239. #define tanh(x) __tg_real_complex(tanh, (x))
  240. #define tgamma(x) __tg_real(tgamma, (x))
  241. #define trunc(x) __tg_real(trunc, (x))
  242. #endif