Updated to fedora-glibc-20050523T1354
[kopensolaris-gnu/glibc.git] / math / tgmath.h
1 /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 /*
21  *      ISO C99 Standard: 7.22 Type-generic math        <tgmath.h>
22  */
23
24 #ifndef _TGMATH_H
25 #define _TGMATH_H       1
26
27 /* Include the needed headers.  */
28 #include <math.h>
29 #include <complex.h>
30
31
32 /* Since `complex' is currently not really implemented in most C compilers
33    and if it is implemented, the implementations differ.  This makes it
34    quite difficult to write a generic implementation of this header.  We
35    do not try this for now and instead concentrate only on GNU CC.  Once
36    we have more information support for other compilers might follow.  */
37
38 #if __GNUC_PREREQ (2, 7)
39
40 # ifdef __NO_LONG_DOUBLE_MATH
41 #  define __tgml(fct) fct
42 # else
43 #  define __tgml(fct) fct ## l
44 # endif
45
46 /* This is ugly but unless gcc gets appropriate builtins we have to do
47    something like this.  Don't ask how it works.  */
48
49 /* 1 if 'type' is a floating type, 0 if 'type' is an integer type.
50    Allows for _Bool.  Expands to an integer constant expression.  */
51 # define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1))
52
53 /* The tgmath real type for T, where E is 0 if T is an integer type and
54    1 for a floating type.  */
55 # define __tgmath_real_type_sub(T, E) \
56   __typeof__(*(0 ? (__typeof__ (0 ? (double *) 0 : (void *) (E))) 0           \
57                  : (__typeof__ (0 ? (T *) 0 : (void *) (!(E)))) 0))
58
59 /* The tgmath real type of EXPR.  */
60 # define __tgmath_real_type(expr) \
61   __tgmath_real_type_sub(__typeof__(expr), __floating_type(__typeof__(expr)))
62
63
64 /* We have two kinds of generic macros: to support functions which are
65    only defined on real valued parameters and those which are defined
66    for complex functions as well.  */
67 # define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \
68      (__extension__ ({ __tgmath_real_type (Val) __tgmres;                     \
69                        if (sizeof (Val) == sizeof (double)                    \
70                            || __builtin_classify_type (Val) != 8)             \
71                          __tgmres = Fct (Val);                                \
72                        else if (sizeof (Val) == sizeof (float))               \
73                          __tgmres = Fct##f (Val);                             \
74                        else                                                   \
75                          __tgmres = __tgml(Fct) (Val);                        \
76                        __tgmres; }))
77
78 # define __TGMATH_UNARY_REAL_RET_ONLY(Val, RetType, Fct) \
79      (__extension__ ({ RetType __tgmres;                                      \
80                        if (sizeof (Val) == sizeof (double)                    \
81                            || __builtin_classify_type (Val) != 8)             \
82                          __tgmres = Fct (Val);                                \
83                        else if (sizeof (Val) == sizeof (float))               \
84                          __tgmres = Fct##f (Val);                             \
85                        else                                                   \
86                          __tgmres = __tgml(Fct) (Val);                        \
87                        __tgmres; }))
88
89 # define __TGMATH_BINARY_FIRST_REAL_ONLY(Val1, Val2, Fct) \
90      (__extension__ ({ __tgmath_real_type (Val1) __tgmres;                    \
91                        if (sizeof (Val1) == sizeof (double)                   \
92                            || __builtin_classify_type (Val1) != 8)            \
93                          __tgmres = Fct (Val1, Val2);                         \
94                        else if (sizeof (Val1) == sizeof (float))              \
95                          __tgmres = Fct##f (Val1, Val2);                      \
96                        else                                                   \
97                          __tgmres = __tgml(Fct) (Val1, Val2);                 \
98                        __tgmres; }))
99
100 # define __TGMATH_BINARY_REAL_ONLY(Val1, Val2, Fct) \
101      (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres;         \
102                        if ((sizeof (Val1) > sizeof (double)                   \
103                             || sizeof (Val2) > sizeof (double))               \
104                            && __builtin_classify_type ((Val1) + (Val2)) == 8) \
105                          __tgmres = __tgml(Fct) (Val1, Val2);                 \
106                        else if (sizeof (Val1) == sizeof (double)              \
107                                 || sizeof (Val2) == sizeof (double)           \
108                                 || __builtin_classify_type (Val1) != 8        \
109                                 || __builtin_classify_type (Val2) != 8)       \
110                          __tgmres = Fct (Val1, Val2);                         \
111                        else                                                   \
112                          __tgmres = Fct##f (Val1, Val2);                      \
113                        __tgmres; }))
114
115 # define __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY(Val1, Val2, Val3, Fct) \
116      (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres;         \
117                        if ((sizeof (Val1) > sizeof (double)                   \
118                             || sizeof (Val2) > sizeof (double))               \
119                            && __builtin_classify_type ((Val1) + (Val2)) == 8) \
120                          __tgmres = __tgml(Fct) (Val1, Val2, Val3);           \
121                        else if (sizeof (Val1) == sizeof (double)              \
122                                 || sizeof (Val2) == sizeof (double)           \
123                                 || __builtin_classify_type (Val1) != 8        \
124                                 || __builtin_classify_type (Val2) != 8)       \
125                          __tgmres = Fct (Val1, Val2, Val3);                   \
126                        else                                                   \
127                          __tgmres = Fct##f (Val1, Val2, Val3);                \
128                        __tgmres; }))
129
130 # define __TGMATH_TERNARY_REAL_ONLY(Val1, Val2, Val3, Fct) \
131      (__extension__ ({ __tgmath_real_type ((Val1) + (Val2) + (Val3)) __tgmres;\
132                        if ((sizeof (Val1) > sizeof (double)                   \
133                             || sizeof (Val2) > sizeof (double)                \
134                             || sizeof (Val3) > sizeof (double))               \
135                            && __builtin_classify_type ((Val1) + (Val2)        \
136                                                        + (Val3)) == 8)        \
137                          __tgmres = __tgml(Fct) (Val1, Val2, Val3);           \
138                        else if (sizeof (Val1) == sizeof (double)              \
139                                 || sizeof (Val2) == sizeof (double)           \
140                                 || sizeof (Val3) == sizeof (double)           \
141                                 || __builtin_classify_type (Val1) != 8        \
142                                 || __builtin_classify_type (Val2) != 8        \
143                                 || __builtin_classify_type (Val3) != 8)       \
144                          __tgmres = Fct (Val1, Val2, Val3);                   \
145                        else                                                   \
146                          __tgmres = Fct##f (Val1, Val2, Val3);                \
147                        __tgmres; }))
148
149 /* XXX This definition has to be changed as soon as the compiler understands
150    the imaginary keyword.  */
151 # define __TGMATH_UNARY_REAL_IMAG(Val, Fct, Cfct) \
152      (__extension__ ({ __tgmath_real_type (Val) __tgmres;                     \
153                        if (sizeof (__real__ (Val)) > sizeof (double)          \
154                            && __builtin_classify_type (__real__ (Val)) == 8)  \
155                          {                                                    \
156                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
157                              __tgmres = __tgml(Fct) (Val);                    \
158                            else                                               \
159                              __tgmres = __tgml(Cfct) (Val);                   \
160                          }                                                    \
161                        else if (sizeof (__real__ (Val)) == sizeof (double)    \
162                                 || __builtin_classify_type (__real__ (Val))   \
163                                    != 8)                                      \
164                          {                                                    \
165                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
166                              __tgmres = Fct (Val);                            \
167                            else                                               \
168                              __tgmres = Cfct (Val);                           \
169                          }                                                    \
170                        else                                                   \
171                          {                                                    \
172                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
173                              __tgmres = Fct##f (Val);                         \
174                            else                                               \
175                              __tgmres = Cfct##f (Val);                        \
176                          }                                                    \
177                        __tgmres; }))
178
179 /* XXX This definition has to be changed as soon as the compiler understands
180    the imaginary keyword.  */
181 # define __TGMATH_UNARY_REAL_IMAG_RET_REAL(Val, Fct, Cfct) \
182      (__extension__ ({ __tgmath_real_type (Val) __tgmres;                     \
183                        if (sizeof (__real__ (Val)) > sizeof (double)          \
184                            && __builtin_classify_type (__real__ (Val)) == 8)  \
185                          {                                                    \
186                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
187                              __tgmres = __tgml(Fct) (Val);                    \
188                            else                                               \
189                              __tgmres = __tgml(Cfct) (Val);                   \
190                          }                                                    \
191                        else if (sizeof (__real__ (Val)) == sizeof (double)    \
192                                 || __builtin_classify_type (__real__ (Val))   \
193                                    != 8)                                      \
194                          {                                                    \
195                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
196                              __tgmres = Fct (Val);                            \
197                            else                                               \
198                              __tgmres = Cfct (Val);                           \
199                          }                                                    \
200                        else                                                   \
201                          {                                                    \
202                            if (sizeof (__real__ (Val)) == sizeof (Val))       \
203                              __tgmres = Fct##f (Val);                         \
204                            else                                               \
205                              __tgmres = Cfct##f (Val);                        \
206                          }                                                    \
207                        __real__ __tgmres; }))
208
209 /* XXX This definition has to be changed as soon as the compiler understands
210    the imaginary keyword.  */
211 # define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \
212      (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres;         \
213                        if ((sizeof (__real__ (Val1)) > sizeof (double)        \
214                             || sizeof (__real__ (Val2)) > sizeof (double))    \
215                            && __builtin_classify_type (__real__ (Val1)        \
216                                                        + __real__ (Val2))     \
217                               == 8)                                           \
218                          {                                                    \
219                            if (sizeof (__real__ (Val1)) == sizeof (Val1)      \
220                                && sizeof (__real__ (Val2)) == sizeof (Val2))  \
221                              __tgmres = __tgml(Fct) (Val1, Val2);             \
222                            else                                               \
223                              __tgmres = __tgml(Cfct) (Val1, Val2);            \
224                          }                                                    \
225                        else if (sizeof (__real__ (Val1)) == sizeof (double)   \
226                                 || sizeof (__real__ (Val2)) == sizeof(double) \
227                                 || (__builtin_classify_type (__real__ (Val1)) \
228                                     != 8)                                     \
229                                 || (__builtin_classify_type (__real__ (Val2)) \
230                                     != 8))                                    \
231                          {                                                    \
232                            if (sizeof (__real__ (Val1)) == sizeof (Val1)      \
233                                && sizeof (__real__ (Val2)) == sizeof (Val2))  \
234                              __tgmres = Fct (Val1, Val2);                     \
235                            else                                               \
236                              __tgmres = Cfct (Val1, Val2);                    \
237                          }                                                    \
238                        else                                                   \
239                          {                                                    \
240                            if (sizeof (__real__ (Val1)) == sizeof (Val1)      \
241                                && sizeof (__real__ (Val2)) == sizeof (Val2))  \
242                              __tgmres = Fct##f (Val1, Val2);                  \
243                            else                                               \
244                              __tgmres = Cfct##f (Val1, Val2);                 \
245                          }                                                    \
246                        __tgmres; }))
247 #else
248 # error "Unsupported compiler; you cannot use <tgmath.h>"
249 #endif
250
251
252 /* Unary functions defined for real and complex values.  */
253
254
255 /* Trigonometric functions.  */
256
257 /* Arc cosine of X.  */
258 #define acos(Val) __TGMATH_UNARY_REAL_IMAG (Val, acos, cacos)
259 /* Arc sine of X.  */
260 #define asin(Val) __TGMATH_UNARY_REAL_IMAG (Val, asin, casin)
261 /* Arc tangent of X.  */
262 #define atan(Val) __TGMATH_UNARY_REAL_IMAG (Val, atan, catan)
263 /* Arc tangent of Y/X.  */
264 #define atan2(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, atan2)
265
266 /* Cosine of X.  */
267 #define cos(Val) __TGMATH_UNARY_REAL_IMAG (Val, cos, ccos)
268 /* Sine of X.  */
269 #define sin(Val) __TGMATH_UNARY_REAL_IMAG (Val, sin, csin)
270 /* Tangent of X.  */
271 #define tan(Val) __TGMATH_UNARY_REAL_IMAG (Val, tan, ctan)
272
273
274 /* Hyperbolic functions.  */
275
276 /* Hyperbolic arc cosine of X.  */
277 #define acosh(Val) __TGMATH_UNARY_REAL_IMAG (Val, acosh, cacosh)
278 /* Hyperbolic arc sine of X.  */
279 #define asinh(Val) __TGMATH_UNARY_REAL_IMAG (Val, asinh, casinh)
280 /* Hyperbolic arc tangent of X.  */
281 #define atanh(Val) __TGMATH_UNARY_REAL_IMAG (Val, atanh, catanh)
282
283 /* Hyperbolic cosine of X.  */
284 #define cosh(Val) __TGMATH_UNARY_REAL_IMAG (Val, cosh, ccosh)
285 /* Hyperbolic sine of X.  */
286 #define sinh(Val) __TGMATH_UNARY_REAL_IMAG (Val, sinh, csinh)
287 /* Hyperbolic tangent of X.  */
288 #define tanh(Val) __TGMATH_UNARY_REAL_IMAG (Val, tanh, ctanh)
289
290
291 /* Exponential and logarithmic functions.  */
292
293 /* Exponential function of X.  */
294 #define exp(Val) __TGMATH_UNARY_REAL_IMAG (Val, exp, cexp)
295
296 /* Break VALUE into a normalized fraction and an integral power of 2.  */
297 #define frexp(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, frexp)
298
299 /* X times (two to the EXP power).  */
300 #define ldexp(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, ldexp)
301
302 /* Natural logarithm of X.  */
303 #define log(Val) __TGMATH_UNARY_REAL_IMAG (Val, log, clog)
304
305 /* Base-ten logarithm of X.  */
306 #ifdef __USE_GNU
307 # define log10(Val) __TGMATH_UNARY_REAL_IMAG (Val, log10, __clog10)
308 #else
309 # define log10(Val) __TGMATH_UNARY_REAL_ONLY (Val, log10)
310 #endif
311
312 /* Return exp(X) - 1.  */
313 #define expm1(Val) __TGMATH_UNARY_REAL_ONLY (Val, expm1)
314
315 /* Return log(1 + X).  */
316 #define log1p(Val) __TGMATH_UNARY_REAL_ONLY (Val, log1p)
317
318 /* Return the base 2 signed integral exponent of X.  */
319 #define logb(Val) __TGMATH_UNARY_REAL_ONLY (Val, logb)
320
321 /* Compute base-2 exponential of X.  */
322 #define exp2(Val) __TGMATH_UNARY_REAL_ONLY (Val, exp2)
323
324 /* Compute base-2 logarithm of X.  */
325 #define log2(Val) __TGMATH_UNARY_REAL_ONLY (Val, log2)
326
327
328 /* Power functions.  */
329
330 /* Return X to the Y power.  */
331 #define pow(Val1, Val2) __TGMATH_BINARY_REAL_IMAG (Val1, Val2, pow, cpow)
332
333 /* Return the square root of X.  */
334 #define sqrt(Val) __TGMATH_UNARY_REAL_IMAG (Val, sqrt, csqrt)
335
336 /* Return `sqrt(X*X + Y*Y)'.  */
337 #define hypot(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, hypot)
338
339 /* Return the cube root of X.  */
340 #define cbrt(Val) __TGMATH_UNARY_REAL_ONLY (Val, cbrt)
341
342
343 /* Nearest integer, absolute value, and remainder functions.  */
344
345 /* Smallest integral value not less than X.  */
346 #define ceil(Val) __TGMATH_UNARY_REAL_ONLY (Val, ceil)
347
348 /* Absolute value of X.  */
349 #define fabs(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, fabs, cabs)
350
351 /* Largest integer not greater than X.  */
352 #define floor(Val) __TGMATH_UNARY_REAL_ONLY (Val, floor)
353
354 /* Floating-point modulo remainder of X/Y.  */
355 #define fmod(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmod)
356
357 /* Round X to integral valuein floating-point format using current
358    rounding direction, but do not raise inexact exception.  */
359 #define nearbyint(Val) __TGMATH_UNARY_REAL_ONLY (Val, nearbyint)
360
361 /* Round X to nearest integral value, rounding halfway cases away from
362    zero.  */
363 #define round(Val) __TGMATH_UNARY_REAL_ONLY (Val, round)
364
365 /* Round X to the integral value in floating-point format nearest but
366    not larger in magnitude.  */
367 #define trunc(Val) __TGMATH_UNARY_REAL_ONLY (Val, trunc)
368
369 /* Compute remainder of X and Y and put in *QUO a value with sign of x/y
370    and magnitude congruent `mod 2^n' to the magnitude of the integral
371    quotient x/y, with n >= 3.  */
372 #define remquo(Val1, Val2, Val3) \
373      __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY (Val1, Val2, Val3, remquo)
374
375 /* Round X to nearest integral value according to current rounding
376    direction.  */
377 #define lrint(Val) __TGMATH_UNARY_REAL_RET_ONLY (Val, long int, lrint)
378 #define llrint(Val) __TGMATH_UNARY_REAL_RET_ONLY (Val, long long int, llrint)
379
380 /* Round X to nearest integral value, rounding halfway cases away from
381    zero.  */
382 #define lround(Val) __TGMATH_UNARY_REAL_RET_ONLY (Val, long int, lround)
383 #define llround(Val) __TGMATH_UNARY_REAL_RET_ONLY (Val, long long int, llround)
384
385
386 /* Return X with its signed changed to Y's.  */
387 #define copysign(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, copysign)
388
389 /* Error and gamma functions.  */
390 #define erf(Val) __TGMATH_UNARY_REAL_ONLY (Val, erf)
391 #define erfc(Val) __TGMATH_UNARY_REAL_ONLY (Val, erfc)
392 #define tgamma(Val) __TGMATH_UNARY_REAL_ONLY (Val, tgamma)
393 #define lgamma(Val) __TGMATH_UNARY_REAL_ONLY (Val, lgamma)
394
395
396 /* Return the integer nearest X in the direction of the
397    prevailing rounding mode.  */
398 #define rint(Val) __TGMATH_UNARY_REAL_ONLY (Val, rint)
399
400 /* Return X + epsilon if X < Y, X - epsilon if X > Y.  */
401 #define nextafter(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, nextafter)
402 #define nexttoward(Val1, Val2) \
403      __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, nexttoward)
404
405 /* Return the remainder of integer divison X / Y with infinite precision.  */
406 #define remainder(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, remainder)
407
408 /* Return X times (2 to the Nth power).  */
409 #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
410 # define scalb(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, scalb)
411 #endif
412
413 /* Return X times (2 to the Nth power).  */
414 #define scalbn(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, scalbn)
415
416 /* Return X times (2 to the Nth power).  */
417 #define scalbln(Val1, Val2) \
418      __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, scalbln)
419
420 /* Return the binary exponent of X, which must be nonzero.  */
421 #define ilogb(Val) __TGMATH_UNARY_REAL_RET_ONLY (Val, int, ilogb)
422
423
424 /* Return positive difference between X and Y.  */
425 #define fdim(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fdim)
426
427 /* Return maximum numeric value from X and Y.  */
428 #define fmax(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmax)
429
430 /* Return minimum numeric value from X and Y.  */
431 #define fmin(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmin)
432
433
434 /* Multiply-add function computed as a ternary operation.  */
435 #define fma(Val1, Val2, Val3) \
436      __TGMATH_TERNARY_REAL_ONLY (Val1, Val2, Val3, fma)
437
438
439 /* Absolute value, conjugates, and projection.  */
440
441 /* Argument value of Z.  */
442 #define carg(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, carg, carg)
443
444 /* Complex conjugate of Z.  */
445 #define conj(Val) __TGMATH_UNARY_REAL_IMAG (Val, conj, conj)
446
447 /* Projection of Z onto the Riemann sphere.  */
448 #define cproj(Val) __TGMATH_UNARY_REAL_IMAG (Val, cproj, cproj)
449
450
451 /* Decomposing complex values.  */
452
453 /* Imaginary part of Z.  */
454 #define cimag(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, cimag, cimag)
455
456 /* Real part of Z.  */
457 #define creal(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, creal, creal)
458
459 #endif /* tgmath.h */