math: add portability warnings for classification macros
[gnulib.git] / lib / math.in.h
1 /* A GNU-like <math.h>.
2
3    Copyright (C) 2002-2003, 2007-2010 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program 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
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #ifndef _GL_MATH_H
19
20 #if __GNUC__ >= 3
21 @PRAGMA_SYSTEM_HEADER@
22 #endif
23
24 /* The include_next requires a split double-inclusion guard.  */
25 #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
26
27 #ifndef _GL_MATH_H
28 #define _GL_MATH_H
29
30
31 /* The definition of GL_LINK_WARNING is copied here.  */
32
33 /* The definition of _GL_ARG_NONNULL is copied here.  */
34
35 /* Helper macros to define a portability warning for the
36    classification macro FUNC called with VALUE.  POSIX declares the
37    classification macros with an argument of real-floating (that is,
38    one of float, double, or long double).  */
39 #define _GL_WARN_REAL_FLOATING_DECL(func) \
40 static inline int                                                   \
41 rpl_ ## func ## f (float f)                                         \
42 {                                                                   \
43   return func (f);                                                  \
44 }                                                                   \
45 static inline int                                                   \
46 rpl_ ## func ## d (double d)                                        \
47 {                                                                   \
48   return func (d);                                                  \
49 }                                                                   \
50 static inline int                                                   \
51 rpl_ ## func ## l (long double l)                                   \
52 {                                                                   \
53   return func (l);                                                  \
54 }                                                                   \
55 _GL_WARN_ON_USE (rpl_ ## func ## f, #func " is unportable - "       \
56                  "use gnulib module " #func " for portability");    \
57 _GL_WARN_ON_USE (rpl_ ## func ## d, #func " is unportable - "       \
58                  "use gnulib module " #func " for portability");    \
59 _GL_WARN_ON_USE (rpl_ ## func ## l, #func " is unportable - "       \
60                  "use gnulib module " #func " for portability")
61 #define _GL_WARN_REAL_FLOATING_IMPL(func, value) \
62   (sizeof (value) == sizeof (float) ? rpl_ ## func ## f (value)     \
63    : sizeof (value) == sizeof (double) ? rpl_ ## func ## d (value)  \
64    : rpl_ ## func ## l (value))
65
66
67 #ifdef __cplusplus
68 extern "C" {
69 #endif
70
71
72 /* POSIX allows platforms that don't support NAN.  But all major
73    machines in the past 15 years have supported something close to
74    IEEE NaN, so we define this unconditionally.  We also must define
75    it on platforms like Solaris 10, where NAN is present but defined
76    as a function pointer rather than a floating point constant.  */
77 #if !defined NAN || @REPLACE_NAN@
78 # undef NAN
79   /* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0.  */
80 # ifdef __DECC
81 static float
82 _NaN ()
83 {
84   static float zero = 0.0f;
85   return zero / zero;
86 }
87 #  define NAN (_NaN())
88 # else
89 #  define NAN (0.0f / 0.0f)
90 # endif
91 #endif
92
93 /* Solaris 10 defines HUGE_VAL, but as a function pointer rather
94    than a floating point constant.  */
95 #if @REPLACE_HUGE_VAL@
96 # undef HUGE_VAL
97 # define HUGE_VAL (1.0 / 0.0)
98 #endif
99
100 /* Write x as
101      x = mantissa * 2^exp
102    where
103      If x finite and nonzero: 0.5 <= |mantissa| < 1.0.
104      If x is zero: mantissa = x, exp = 0.
105      If x is infinite or NaN: mantissa = x, exp unspecified.
106    Store exp in *EXPPTR and return mantissa.  */
107 #if @GNULIB_FREXP@
108 # if @REPLACE_FREXP@
109 #  define frexp rpl_frexp
110 extern double frexp (double x, int *expptr) _GL_ARG_NONNULL ((2));
111 # endif
112 #elif defined GNULIB_POSIXCHECK
113 # undef frexp
114 # define frexp(x,e) \
115     (GL_LINK_WARNING ("frexp is unportable - " \
116                       "use gnulib module frexp for portability"), \
117      frexp (x, e))
118 #endif
119
120
121 #if @GNULIB_MATHL@ || !@HAVE_DECL_ACOSL@
122 extern long double acosl (long double x);
123 #endif
124 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
125 # undef acosl
126 # define acosl(x) \
127     (GL_LINK_WARNING ("acosl is unportable - " \
128                       "use gnulib module mathl for portability"), \
129      acosl (x))
130 #endif
131
132
133 #if @GNULIB_MATHL@ || !@HAVE_DECL_ASINL@
134 extern long double asinl (long double x);
135 #endif
136 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
137 # undef asinl
138 # define asinl(x) \
139     (GL_LINK_WARNING ("asinl is unportable - " \
140                       "use gnulib module mathl for portability"), \
141      asinl (x))
142 #endif
143
144
145 #if @GNULIB_MATHL@ || !@HAVE_DECL_ATANL@
146 extern long double atanl (long double x);
147 #endif
148 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
149 # undef atanl
150 # define atanl(x) \
151     (GL_LINK_WARNING ("atanl is unportable - " \
152                       "use gnulib module mathl for portability"), \
153      atanl (x))
154 #endif
155
156
157 #if @GNULIB_CEILF@
158 # if @REPLACE_CEILF@
159 #  define ceilf rpl_ceilf
160 extern float ceilf (float x);
161 # endif
162 #elif defined GNULIB_POSIXCHECK
163 # undef ceilf
164 # define ceilf(x) \
165     (GL_LINK_WARNING ("ceilf is unportable - " \
166                       "use gnulib module ceilf for portability"), \
167      ceilf (x))
168 #endif
169
170 #if @GNULIB_CEILL@
171 # if @REPLACE_CEILL@
172 #  define ceill rpl_ceill
173 extern long double ceill (long double x);
174 # endif
175 #elif defined GNULIB_POSIXCHECK
176 # undef ceill
177 # define ceill(x) \
178     (GL_LINK_WARNING ("ceill is unportable - " \
179                       "use gnulib module ceill for portability"), \
180      ceill (x))
181 #endif
182
183
184 #if @GNULIB_MATHL@ || (!@HAVE_DECL_COSL@ && !defined cosl)
185 # undef cosl
186 extern long double cosl (long double x);
187 #endif
188 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
189 # undef cosl
190 # define cosl(x) \
191     (GL_LINK_WARNING ("cosl is unportable - " \
192                       "use gnulib module mathl for portability"), \
193      cosl (x))
194 #endif
195
196
197 #if @GNULIB_MATHL@ || !@HAVE_DECL_EXPL@
198 extern long double expl (long double x);
199 #endif
200 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
201 # undef expl
202 # define expl(x) \
203     (GL_LINK_WARNING ("expl is unportable - " \
204                       "use gnulib module mathl for portability"), \
205      expl (x))
206 #endif
207
208
209 #if @GNULIB_FLOORF@
210 # if @REPLACE_FLOORF@
211 #  define floorf rpl_floorf
212 extern float floorf (float x);
213 # endif
214 #elif defined GNULIB_POSIXCHECK
215 # undef floorf
216 # define floorf(x) \
217     (GL_LINK_WARNING ("floorf is unportable - " \
218                       "use gnulib module floorf for portability"), \
219      floorf (x))
220 #endif
221
222 #if @GNULIB_FLOORL@
223 # if @REPLACE_FLOORL@
224 #  define floorl rpl_floorl
225 extern long double floorl (long double x);
226 # endif
227 #elif defined GNULIB_POSIXCHECK
228 # undef floorl
229 # define floorl(x) \
230     (GL_LINK_WARNING ("floorl is unportable - " \
231                       "use gnulib module floorl for portability"), \
232      floorl (x))
233 #endif
234
235
236 /* Write x as
237      x = mantissa * 2^exp
238    where
239      If x finite and nonzero: 0.5 <= |mantissa| < 1.0.
240      If x is zero: mantissa = x, exp = 0.
241      If x is infinite or NaN: mantissa = x, exp unspecified.
242    Store exp in *EXPPTR and return mantissa.  */
243 #if @GNULIB_FREXPL@ && @REPLACE_FREXPL@
244 # define frexpl rpl_frexpl
245 #endif
246 #if (@GNULIB_FREXPL@ && @REPLACE_FREXPL@) || !@HAVE_DECL_FREXPL@
247 extern long double frexpl (long double x, int *expptr) _GL_ARG_NONNULL ((2));
248 #endif
249 #if !@GNULIB_FREXPL@ && defined GNULIB_POSIXCHECK
250 # undef frexpl
251 # define frexpl(x,e) \
252     (GL_LINK_WARNING ("frexpl is unportable - " \
253                       "use gnulib module frexpl for portability"), \
254      frexpl (x, e))
255 #endif
256
257
258 /* Return x * 2^exp.  */
259 #if @GNULIB_LDEXPL@ && @REPLACE_LDEXPL@
260 # define ldexpl rpl_ldexpl
261 #endif
262 #if (@GNULIB_LDEXPL@ && @REPLACE_LDEXPL@) || !@HAVE_DECL_LDEXPL@
263 extern long double ldexpl (long double x, int exp);
264 #endif
265 #if !@GNULIB_LDEXPL@ && defined GNULIB_POSIXCHECK
266 # undef ldexpl
267 # define ldexpl(x,e) \
268     (GL_LINK_WARNING ("ldexpl is unportable - " \
269                       "use gnulib module ldexpl for portability"), \
270      ldexpl (x, e))
271 #endif
272
273
274 #if @GNULIB_MATHL@ || (!@HAVE_DECL_LOGL@ && !defined logl)
275 # undef logl
276 extern long double logl (long double x);
277 #endif
278 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
279 # undef logl
280 # define logl(x) \
281     (GL_LINK_WARNING ("logl is unportable - " \
282                       "use gnulib module mathl for portability"), \
283      logl (x))
284 #endif
285
286
287 #if @GNULIB_ROUNDF@
288 # if @REPLACE_ROUNDF@
289 #  undef roundf
290 #  define roundf rpl_roundf
291 extern float roundf (float x);
292 # endif
293 #elif defined GNULIB_POSIXCHECK
294 # undef roundf
295 # define roundf(x) \
296     (GL_LINK_WARNING ("roundf is unportable - " \
297                       "use gnulib module roundf for portability"), \
298      roundf (x))
299 #endif
300
301 #if @GNULIB_ROUND@
302 # if @REPLACE_ROUND@
303 #  undef round
304 #  define round rpl_round
305 extern double round (double x);
306 # endif
307 #elif defined GNULIB_POSIXCHECK
308 # undef round
309 # define round(x) \
310     (GL_LINK_WARNING ("round is unportable - " \
311                       "use gnulib module round for portability"), \
312      round (x))
313 #endif
314
315 #if @GNULIB_ROUNDL@
316 # if @REPLACE_ROUNDL@
317 #  undef roundl
318 #  define roundl rpl_roundl
319 extern long double roundl (long double x);
320 # endif
321 #elif defined GNULIB_POSIXCHECK
322 # undef roundl
323 # define roundl(x) \
324     (GL_LINK_WARNING ("roundl is unportable - " \
325                       "use gnulib module roundl for portability"), \
326      roundl (x))
327 #endif
328
329
330 #if @GNULIB_MATHL@ || (!@HAVE_DECL_SINL@ && !defined sinl)
331 # undef sinl
332 extern long double sinl (long double x);
333 #endif
334 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
335 # undef sinl
336 # define sinl(x) \
337     (GL_LINK_WARNING ("sinl is unportable - " \
338                       "use gnulib module mathl for portability"), \
339      sinl (x))
340 #endif
341
342
343 #if @GNULIB_MATHL@ || !@HAVE_DECL_SQRTL@
344 extern long double sqrtl (long double x);
345 #endif
346 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
347 # undef sqrtl
348 # define sqrtl(x) \
349     (GL_LINK_WARNING ("sqrtl is unportable - " \
350                       "use gnulib module mathl for portability"), \
351      sqrtl (x))
352 #endif
353
354
355 #if @GNULIB_MATHL@ || !@HAVE_DECL_TANL@
356 extern long double tanl (long double x);
357 #endif
358 #if !@GNULIB_MATHL@ && defined GNULIB_POSIXCHECK
359 # undef tanl
360 # define tanl(x) \
361     (GL_LINK_WARNING ("tanl is unportable - " \
362                       "use gnulib module mathl for portability"), \
363      tanl (x))
364 #endif
365
366
367 #if @GNULIB_TRUNCF@
368 # if !@HAVE_DECL_TRUNCF@
369 #  define truncf rpl_truncf
370 extern float truncf (float x);
371 # endif
372 #elif defined GNULIB_POSIXCHECK
373 # undef truncf
374 # define truncf(x) \
375     (GL_LINK_WARNING ("truncf is unportable - " \
376                       "use gnulib module truncf for portability"), \
377      truncf (x))
378 #endif
379
380 #if @GNULIB_TRUNC@
381 # if !@HAVE_DECL_TRUNC@
382 #  define trunc rpl_trunc
383 extern double trunc (double x);
384 # endif
385 #elif defined GNULIB_POSIXCHECK
386 # undef trunc
387 # define trunc(x) \
388     (GL_LINK_WARNING ("trunc is unportable - " \
389                       "use gnulib module trunc for portability"), \
390      trunc (x))
391 #endif
392
393 #if @GNULIB_TRUNCL@
394 # if @REPLACE_TRUNCL@
395 #  undef truncl
396 #  define truncl rpl_truncl
397 extern long double truncl (long double x);
398 # endif
399 #elif defined GNULIB_POSIXCHECK
400 # undef truncl
401 # define truncl(x) \
402     (GL_LINK_WARNING ("truncl is unportable - " \
403                       "use gnulib module truncl for portability"), \
404      truncl (x))
405 #endif
406
407
408 #if @GNULIB_ISFINITE@
409 # if @REPLACE_ISFINITE@
410 extern int gl_isfinitef (float x);
411 extern int gl_isfinited (double x);
412 extern int gl_isfinitel (long double x);
413 #  undef isfinite
414 #  define isfinite(x) \
415    (sizeof (x) == sizeof (long double) ? gl_isfinitel (x) : \
416     sizeof (x) == sizeof (double) ? gl_isfinited (x) : \
417     gl_isfinitef (x))
418 # endif
419 #elif defined GNULIB_POSIXCHECK
420 # if defined isfinite
421 _GL_WARN_REAL_FLOATING_DECL (isfinite);
422 #  undef isfinite
423 #  define isfinite(x) _GL_WARN_REAL_FLOATING_IMPL (isfinite, x)
424 # endif
425 #endif
426
427
428 #if @GNULIB_ISINF@
429 # if @REPLACE_ISINF@
430 extern int gl_isinff (float x);
431 extern int gl_isinfd (double x);
432 extern int gl_isinfl (long double x);
433 #  undef isinf
434 #  define isinf(x) \
435    (sizeof (x) == sizeof (long double) ? gl_isinfl (x) : \
436     sizeof (x) == sizeof (double) ? gl_isinfd (x) : \
437     gl_isinff (x))
438 # endif
439 #elif defined GNULIB_POSIXCHECK
440 # if defined isinf
441 _GL_WARN_REAL_FLOATING_DECL (isinf);
442 #  undef isinf
443 #  define isinf(x) _GL_WARN_REAL_FLOATING_IMPL (isinf, x)
444 # endif
445 #endif
446
447
448 #if @GNULIB_ISNANF@
449 /* Test for NaN for 'float' numbers.  */
450 # if @HAVE_ISNANF@
451 /* The original <math.h> included above provides a declaration of isnan macro
452    or (older) isnanf function.  */
453 #  if __GNUC__ >= 4
454     /* GCC 4.0 and newer provides three built-ins for isnan.  */
455 #   undef isnanf
456 #   define isnanf(x) __builtin_isnanf ((float)(x))
457 #  elif defined isnan
458 #   undef isnanf
459 #   define isnanf(x) isnan ((float)(x))
460 #  endif
461 # else
462 /* Test whether X is a NaN.  */
463 #  undef isnanf
464 #  define isnanf rpl_isnanf
465 extern int isnanf (float x);
466 # endif
467 #endif
468
469 #if @GNULIB_ISNAND@
470 /* Test for NaN for 'double' numbers.
471    This function is a gnulib extension, unlike isnan() which applied only
472    to 'double' numbers earlier but now is a type-generic macro.  */
473 # if @HAVE_ISNAND@
474 /* The original <math.h> included above provides a declaration of isnan macro.  */
475 #  if __GNUC__ >= 4
476     /* GCC 4.0 and newer provides three built-ins for isnan.  */
477 #   undef isnand
478 #   define isnand(x) __builtin_isnan ((double)(x))
479 #  else
480 #   undef isnand
481 #   define isnand(x) isnan ((double)(x))
482 #  endif
483 # else
484 /* Test whether X is a NaN.  */
485 #  undef isnand
486 #  define isnand rpl_isnand
487 extern int isnand (double x);
488 # endif
489 #endif
490
491 #if @GNULIB_ISNANL@
492 /* Test for NaN for 'long double' numbers.  */
493 # if @HAVE_ISNANL@
494 /* The original <math.h> included above provides a declaration of isnan macro or (older) isnanl function.  */
495 #  if __GNUC__ >= 4
496     /* GCC 4.0 and newer provides three built-ins for isnan.  */
497 #   undef isnanl
498 #   define isnanl(x) __builtin_isnanl ((long double)(x))
499 #  elif defined isnan
500 #   undef isnanl
501 #   define isnanl(x) isnan ((long double)(x))
502 #  endif
503 # else
504 /* Test whether X is a NaN.  */
505 #  undef isnanl
506 #  define isnanl rpl_isnanl
507 extern int isnanl (long double x);
508 # endif
509 #endif
510
511 /* This must come *after* the snippets for GNULIB_ISNANF and GNULIB_ISNANL!  */
512 #if @GNULIB_ISNAN@
513 # if @REPLACE_ISNAN@
514 /* We can't just use the isnanf macro (e.g.) as exposed by
515    isnanf.h (e.g.) here, because those may end up being macros
516    that recursively expand back to isnan.  So use the gnulib
517    replacements for them directly. */
518 #  if @HAVE_ISNANF@ && __GNUC__ >= 4
519 #   define gl_isnan_f(x) __builtin_isnan ((float)(x))
520 #  else
521 extern int rpl_isnanf (float x);
522 #   define gl_isnan_f(x) rpl_isnanf (x)
523 #  endif
524 #  if @HAVE_ISNAND@ && __GNUC__ >= 4
525 #   define gl_isnan_d(x) __builtin_isnan ((double)(x))
526 #  else
527 extern int rpl_isnand (double x);
528 #   define gl_isnan_d(x) rpl_isnand (x)
529 #  endif
530 #  if @HAVE_ISNANL@ && __GNUC__ >= 4
531 #   define gl_isnan_l(x) __builtin_isnan ((long double)(x))
532 #  else
533 extern int rpl_isnanl (long double x);
534 #   define gl_isnan_l(x) rpl_isnanl (x)
535 #  endif
536 #  undef isnan
537 #  define isnan(x) \
538    (sizeof (x) == sizeof (long double) ? gl_isnan_l (x) : \
539     sizeof (x) == sizeof (double) ? gl_isnan_d (x) : \
540     gl_isnan_f (x))
541 # endif
542 #elif defined GNULIB_POSIXCHECK
543 # if defined isnan
544 _GL_WARN_REAL_FLOATING_DECL (isnan);
545 #  undef isnan
546 #  define isnan(x) _GL_WARN_REAL_FLOATING_IMPL (isnan, x)
547 # endif
548 #endif
549
550
551 #if @GNULIB_SIGNBIT@
552 # if @REPLACE_SIGNBIT_USING_GCC@
553 #  undef signbit
554    /* GCC 4.0 and newer provides three built-ins for signbit.  */
555 #  define signbit(x) \
556    (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
557     sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
558     __builtin_signbitf (x))
559 # endif
560 # if @REPLACE_SIGNBIT@
561 #  undef signbit
562 extern int gl_signbitf (float arg);
563 extern int gl_signbitd (double arg);
564 extern int gl_signbitl (long double arg);
565 #  if __GNUC__ >= 2 && !__STRICT_ANSI__
566 #   if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT && !defined gl_signbitf
567 #    define gl_signbitf_OPTIMIZED_MACRO
568 #    define gl_signbitf(arg) \
569        ({ union { float _value;                                         \
570                   unsigned int _word[(sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
571                 } _m;                                                   \
572           _m._value = (arg);                                            \
573           (_m._word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1;          \
574         })
575 #   endif
576 #   if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT && !defined gl_signbitd
577 #    define gl_signbitd_OPTIMIZED_MACRO
578 #    define gl_signbitd(arg) \
579        ({ union { double _value;                                                \
580                   unsigned int _word[(sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
581                 } _m;                                                   \
582           _m._value = (arg);                                            \
583           (_m._word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1;          \
584         })
585 #   endif
586 #   if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT && !defined gl_signbitl
587 #    define gl_signbitl_OPTIMIZED_MACRO
588 #    define gl_signbitl(arg) \
589        ({ union { long double _value;                                   \
590                   unsigned int _word[(sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
591                 } _m;                                                   \
592           _m._value = (arg);                                            \
593           (_m._word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1;                \
594         })
595 #   endif
596 #  endif
597 #  define signbit(x) \
598    (sizeof (x) == sizeof (long double) ? gl_signbitl (x) : \
599     sizeof (x) == sizeof (double) ? gl_signbitd (x) : \
600     gl_signbitf (x))
601 # endif
602 #elif defined GNULIB_POSIXCHECK
603 # if defined signbit
604 _GL_WARN_REAL_FLOATING_DECL (signbit);
605 #  undef signbit
606 #  define signbit(x) _GL_WARN_REAL_FLOATING_IMPL (signbit, x)
607 # endif
608 #endif
609
610
611 #ifdef __cplusplus
612 }
613 #endif
614
615 #endif /* _GL_MATH_H */
616 #endif /* _GL_MATH_H */