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) \
40static inline int                                                   \
41rpl_ ## func ## f (float f)                                         \
42{                                                                   \
43  return func (f);                                                  \
44}                                                                   \
45static inline int                                                   \
46rpl_ ## func ## d (double d)                                        \
47{                                                                   \
48  return func (d);                                                  \
49}                                                                   \
50static inline int                                                   \
51rpl_ ## 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
68extern "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
81static 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
110extern 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@
122extern 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@
134extern 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@
146extern 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
160extern 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
173extern 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
186extern 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@
198extern 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
212extern 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
225extern 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@
247extern 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@
263extern 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
276extern 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
291extern 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
305extern 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
319extern 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
332extern 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@
344extern 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@
356extern 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
370extern 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
383extern 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
397extern 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@
410extern int gl_isfinitef (float x);
411extern int gl_isfinited (double x);
412extern 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@
430extern int gl_isinff (float x);
431extern int gl_isinfd (double x);
432extern 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
465extern 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
487extern 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
507extern 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
521extern 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
527extern 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
533extern 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
562extern int gl_signbitf (float arg);
563extern int gl_signbitd (double arg);
564extern 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 */
617