4e21cf95cb6fc346b30e2b1ebe6b5820f60ad772
[debian/gzip] / 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_ACOSL@
122 # if !@HAVE_ACOSL@ || !@HAVE_DECL_ACOSL@
123 extern long double acosl (long double x);
124 # endif
125 #elif defined GNULIB_POSIXCHECK
126 # undef acosl
127 # define acosl(x) \
128     (GL_LINK_WARNING ("acosl is unportable - " \
129                       "use gnulib module mathl for portability"), \
130      acosl (x))
131 #endif
132
133
134 #if @GNULIB_ASINL@
135 # if !@HAVE_ASINL@ || !@HAVE_DECL_ASINL@
136 extern long double asinl (long double x);
137 # endif
138 #elif defined GNULIB_POSIXCHECK
139 # undef asinl
140 # define asinl(x) \
141     (GL_LINK_WARNING ("asinl is unportable - " \
142                       "use gnulib module mathl for portability"), \
143      asinl (x))
144 #endif
145
146
147 #if @GNULIB_ATANL@
148 # if !@HAVE_ATANL@ || !@HAVE_DECL_ATANL@
149 extern long double atanl (long double x);
150 # endif
151 #elif defined GNULIB_POSIXCHECK
152 # undef atanl
153 # define atanl(x) \
154     (GL_LINK_WARNING ("atanl is unportable - " \
155                       "use gnulib module mathl for portability"), \
156      atanl (x))
157 #endif
158
159
160 #if @GNULIB_CEILF@
161 # if @REPLACE_CEILF@
162 #  define ceilf rpl_ceilf
163 extern float ceilf (float x);
164 # endif
165 #elif defined GNULIB_POSIXCHECK
166 # undef ceilf
167 # define ceilf(x) \
168     (GL_LINK_WARNING ("ceilf is unportable - " \
169                       "use gnulib module ceilf for portability"), \
170      ceilf (x))
171 #endif
172
173 #if @GNULIB_CEILL@
174 # if @REPLACE_CEILL@
175 #  define ceill rpl_ceill
176 extern long double ceill (long double x);
177 # endif
178 #elif defined GNULIB_POSIXCHECK
179 # undef ceill
180 # define ceill(x) \
181     (GL_LINK_WARNING ("ceill is unportable - " \
182                       "use gnulib module ceill for portability"), \
183      ceill (x))
184 #endif
185
186
187 #if @GNULIB_COSL@
188 # if !@HAVE_COSL@
189 #  undef cosl
190 #  define cosl rpl_cosl
191 # endif
192 # if !@HAVE_COSL@ || !@HAVE_DECL_COSL@
193 extern long double cosl (long double x);
194 # endif
195 #elif defined GNULIB_POSIXCHECK
196 # undef cosl
197 # define cosl(x) \
198     (GL_LINK_WARNING ("cosl is unportable - " \
199                       "use gnulib module mathl for portability"), \
200      cosl (x))
201 #endif
202
203
204 #if @GNULIB_EXPL@
205 # if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@
206 extern long double expl (long double x);
207 # endif
208 #elif defined GNULIB_POSIXCHECK
209 # undef expl
210 # define expl(x) \
211     (GL_LINK_WARNING ("expl is unportable - " \
212                       "use gnulib module mathl for portability"), \
213      expl (x))
214 #endif
215
216
217 #if @GNULIB_FLOORF@
218 # if @REPLACE_FLOORF@
219 #  define floorf rpl_floorf
220 extern float floorf (float x);
221 # endif
222 #elif defined GNULIB_POSIXCHECK
223 # undef floorf
224 # define floorf(x) \
225     (GL_LINK_WARNING ("floorf is unportable - " \
226                       "use gnulib module floorf for portability"), \
227      floorf (x))
228 #endif
229
230 #if @GNULIB_FLOORL@
231 # if @REPLACE_FLOORL@
232 #  define floorl rpl_floorl
233 extern long double floorl (long double x);
234 # endif
235 #elif defined GNULIB_POSIXCHECK
236 # undef floorl
237 # define floorl(x) \
238     (GL_LINK_WARNING ("floorl is unportable - " \
239                       "use gnulib module floorl for portability"), \
240      floorl (x))
241 #endif
242
243
244 /* Write x as
245      x = mantissa * 2^exp
246    where
247      If x finite and nonzero: 0.5 <= |mantissa| < 1.0.
248      If x is zero: mantissa = x, exp = 0.
249      If x is infinite or NaN: mantissa = x, exp unspecified.
250    Store exp in *EXPPTR and return mantissa.  */
251 #if @GNULIB_FREXPL@ && @REPLACE_FREXPL@
252 # define frexpl rpl_frexpl
253 #endif
254 #if (@GNULIB_FREXPL@ && @REPLACE_FREXPL@) || !@HAVE_DECL_FREXPL@
255 extern long double frexpl (long double x, int *expptr) _GL_ARG_NONNULL ((2));
256 #endif
257 #if !@GNULIB_FREXPL@ && defined GNULIB_POSIXCHECK
258 # undef frexpl
259 # define frexpl(x,e) \
260     (GL_LINK_WARNING ("frexpl is unportable - " \
261                       "use gnulib module frexpl for portability"), \
262      frexpl (x, e))
263 #endif
264
265
266 /* Return x * 2^exp.  */
267 #if @GNULIB_LDEXPL@ && @REPLACE_LDEXPL@
268 # define ldexpl rpl_ldexpl
269 #endif
270 #if (@GNULIB_LDEXPL@ && @REPLACE_LDEXPL@) || !@HAVE_DECL_LDEXPL@
271 extern long double ldexpl (long double x, int exp);
272 #endif
273 #if !@GNULIB_LDEXPL@ && defined GNULIB_POSIXCHECK
274 # undef ldexpl
275 # define ldexpl(x,e) \
276     (GL_LINK_WARNING ("ldexpl is unportable - " \
277                       "use gnulib module ldexpl for portability"), \
278      ldexpl (x, e))
279 #endif
280
281
282 #if @GNULIB_LOGL@
283 # if !@HAVE_LOGL@
284 #  undef logl
285 #  define logl rpl_logl
286 # endif
287 # if !@HAVE_LOGL@ || !@HAVE_DECL_LOGL@
288 extern long double logl (long double x);
289 # endif
290 #elif defined GNULIB_POSIXCHECK
291 # undef logl
292 # define logl(x) \
293     (GL_LINK_WARNING ("logl is unportable - " \
294                       "use gnulib module mathl for portability"), \
295      logl (x))
296 #endif
297
298
299 #if @GNULIB_ROUNDF@
300 # if @REPLACE_ROUNDF@
301 #  undef roundf
302 #  define roundf rpl_roundf
303 extern float roundf (float x);
304 # endif
305 #elif defined GNULIB_POSIXCHECK
306 # undef roundf
307 # define roundf(x) \
308     (GL_LINK_WARNING ("roundf is unportable - " \
309                       "use gnulib module roundf for portability"), \
310      roundf (x))
311 #endif
312
313 #if @GNULIB_ROUND@
314 # if @REPLACE_ROUND@
315 #  undef round
316 #  define round rpl_round
317 extern double round (double x);
318 # endif
319 #elif defined GNULIB_POSIXCHECK
320 # undef round
321 # define round(x) \
322     (GL_LINK_WARNING ("round is unportable - " \
323                       "use gnulib module round for portability"), \
324      round (x))
325 #endif
326
327 #if @GNULIB_ROUNDL@
328 # if @REPLACE_ROUNDL@
329 #  undef roundl
330 #  define roundl rpl_roundl
331 extern long double roundl (long double x);
332 # endif
333 #elif defined GNULIB_POSIXCHECK
334 # undef roundl
335 # define roundl(x) \
336     (GL_LINK_WARNING ("roundl is unportable - " \
337                       "use gnulib module roundl for portability"), \
338      roundl (x))
339 #endif
340
341
342 #if @GNULIB_SINL@
343 # if !@HAVE_SINL@
344 #  undef sinl
345 #  define sinl rpl_sinl
346 # endif
347 # if !@HAVE_SINL@ || !@HAVE_DECL_SINL@
348 extern long double sinl (long double x);
349 # endif
350 #elif defined GNULIB_POSIXCHECK
351 # undef sinl
352 # define sinl(x) \
353     (GL_LINK_WARNING ("sinl is unportable - " \
354                       "use gnulib module mathl for portability"), \
355      sinl (x))
356 #endif
357
358
359 #if @GNULIB_SQRTL@
360 # if !@HAVE_SQRTL@ || !@HAVE_DECL_SQRTL@
361 extern long double sqrtl (long double x);
362 # endif
363 #elif defined GNULIB_POSIXCHECK
364 # undef sqrtl
365 # define sqrtl(x) \
366     (GL_LINK_WARNING ("sqrtl is unportable - " \
367                       "use gnulib module mathl for portability"), \
368      sqrtl (x))
369 #endif
370
371
372 #if @GNULIB_TANL@
373 # if !@HAVE_TANL@ || !@HAVE_DECL_TANL@
374 extern long double tanl (long double x);
375 # endif
376 #elif defined GNULIB_POSIXCHECK
377 # undef tanl
378 # define tanl(x) \
379     (GL_LINK_WARNING ("tanl is unportable - " \
380                       "use gnulib module mathl for portability"), \
381      tanl (x))
382 #endif
383
384
385 #if @GNULIB_TRUNCF@
386 # if !@HAVE_DECL_TRUNCF@
387 #  define truncf rpl_truncf
388 extern float truncf (float x);
389 # endif
390 #elif defined GNULIB_POSIXCHECK
391 # undef truncf
392 # define truncf(x) \
393     (GL_LINK_WARNING ("truncf is unportable - " \
394                       "use gnulib module truncf for portability"), \
395      truncf (x))
396 #endif
397
398 #if @GNULIB_TRUNC@
399 # if !@HAVE_DECL_TRUNC@
400 #  define trunc rpl_trunc
401 extern double trunc (double x);
402 # endif
403 #elif defined GNULIB_POSIXCHECK
404 # undef trunc
405 # define trunc(x) \
406     (GL_LINK_WARNING ("trunc is unportable - " \
407                       "use gnulib module trunc for portability"), \
408      trunc (x))
409 #endif
410
411 #if @GNULIB_TRUNCL@
412 # if @REPLACE_TRUNCL@
413 #  undef truncl
414 #  define truncl rpl_truncl
415 extern long double truncl (long double x);
416 # endif
417 #elif defined GNULIB_POSIXCHECK
418 # undef truncl
419 # define truncl(x) \
420     (GL_LINK_WARNING ("truncl is unportable - " \
421                       "use gnulib module truncl for portability"), \
422      truncl (x))
423 #endif
424
425
426 #if @GNULIB_ISFINITE@
427 # if @REPLACE_ISFINITE@
428 extern int gl_isfinitef (float x);
429 extern int gl_isfinited (double x);
430 extern int gl_isfinitel (long double x);
431 #  undef isfinite
432 #  define isfinite(x) \
433    (sizeof (x) == sizeof (long double) ? gl_isfinitel (x) : \
434     sizeof (x) == sizeof (double) ? gl_isfinited (x) : \
435     gl_isfinitef (x))
436 # endif
437 #elif defined GNULIB_POSIXCHECK
438 # if defined isfinite
439 _GL_WARN_REAL_FLOATING_DECL (isfinite);
440 #  undef isfinite
441 #  define isfinite(x) _GL_WARN_REAL_FLOATING_IMPL (isfinite, x)
442 # endif
443 #endif
444
445
446 #if @GNULIB_ISINF@
447 # if @REPLACE_ISINF@
448 extern int gl_isinff (float x);
449 extern int gl_isinfd (double x);
450 extern int gl_isinfl (long double x);
451 #  undef isinf
452 #  define isinf(x) \
453    (sizeof (x) == sizeof (long double) ? gl_isinfl (x) : \
454     sizeof (x) == sizeof (double) ? gl_isinfd (x) : \
455     gl_isinff (x))
456 # endif
457 #elif defined GNULIB_POSIXCHECK
458 # if defined isinf
459 _GL_WARN_REAL_FLOATING_DECL (isinf);
460 #  undef isinf
461 #  define isinf(x) _GL_WARN_REAL_FLOATING_IMPL (isinf, x)
462 # endif
463 #endif
464
465
466 #if @GNULIB_ISNANF@
467 /* Test for NaN for 'float' numbers.  */
468 # if @HAVE_ISNANF@
469 /* The original <math.h> included above provides a declaration of isnan macro
470    or (older) isnanf function.  */
471 #  if __GNUC__ >= 4
472     /* GCC 4.0 and newer provides three built-ins for isnan.  */
473 #   undef isnanf
474 #   define isnanf(x) __builtin_isnanf ((float)(x))
475 #  elif defined isnan
476 #   undef isnanf
477 #   define isnanf(x) isnan ((float)(x))
478 #  endif
479 # else
480 /* Test whether X is a NaN.  */
481 #  undef isnanf
482 #  define isnanf rpl_isnanf
483 extern int isnanf (float x);
484 # endif
485 #endif
486
487 #if @GNULIB_ISNAND@
488 /* Test for NaN for 'double' numbers.
489    This function is a gnulib extension, unlike isnan() which applied only
490    to 'double' numbers earlier but now is a type-generic macro.  */
491 # if @HAVE_ISNAND@
492 /* The original <math.h> included above provides a declaration of isnan macro.  */
493 #  if __GNUC__ >= 4
494     /* GCC 4.0 and newer provides three built-ins for isnan.  */
495 #   undef isnand
496 #   define isnand(x) __builtin_isnan ((double)(x))
497 #  else
498 #   undef isnand
499 #   define isnand(x) isnan ((double)(x))
500 #  endif
501 # else
502 /* Test whether X is a NaN.  */
503 #  undef isnand
504 #  define isnand rpl_isnand
505 extern int isnand (double x);
506 # endif
507 #endif
508
509 #if @GNULIB_ISNANL@
510 /* Test for NaN for 'long double' numbers.  */
511 # if @HAVE_ISNANL@
512 /* The original <math.h> included above provides a declaration of isnan macro or (older) isnanl function.  */
513 #  if __GNUC__ >= 4
514     /* GCC 4.0 and newer provides three built-ins for isnan.  */
515 #   undef isnanl
516 #   define isnanl(x) __builtin_isnanl ((long double)(x))
517 #  elif defined isnan
518 #   undef isnanl
519 #   define isnanl(x) isnan ((long double)(x))
520 #  endif
521 # else
522 /* Test whether X is a NaN.  */
523 #  undef isnanl
524 #  define isnanl rpl_isnanl
525 extern int isnanl (long double x);
526 # endif
527 #endif
528
529 /* This must come *after* the snippets for GNULIB_ISNANF and GNULIB_ISNANL!  */
530 #if @GNULIB_ISNAN@
531 # if @REPLACE_ISNAN@
532 /* We can't just use the isnanf macro (e.g.) as exposed by
533    isnanf.h (e.g.) here, because those may end up being macros
534    that recursively expand back to isnan.  So use the gnulib
535    replacements for them directly. */
536 #  if @HAVE_ISNANF@ && __GNUC__ >= 4
537 #   define gl_isnan_f(x) __builtin_isnan ((float)(x))
538 #  else
539 extern int rpl_isnanf (float x);
540 #   define gl_isnan_f(x) rpl_isnanf (x)
541 #  endif
542 #  if @HAVE_ISNAND@ && __GNUC__ >= 4
543 #   define gl_isnan_d(x) __builtin_isnan ((double)(x))
544 #  else
545 extern int rpl_isnand (double x);
546 #   define gl_isnan_d(x) rpl_isnand (x)
547 #  endif
548 #  if @HAVE_ISNANL@ && __GNUC__ >= 4
549 #   define gl_isnan_l(x) __builtin_isnan ((long double)(x))
550 #  else
551 extern int rpl_isnanl (long double x);
552 #   define gl_isnan_l(x) rpl_isnanl (x)
553 #  endif
554 #  undef isnan
555 #  define isnan(x) \
556    (sizeof (x) == sizeof (long double) ? gl_isnan_l (x) : \
557     sizeof (x) == sizeof (double) ? gl_isnan_d (x) : \
558     gl_isnan_f (x))
559 # endif
560 #elif defined GNULIB_POSIXCHECK
561 # if defined isnan
562 _GL_WARN_REAL_FLOATING_DECL (isnan);
563 #  undef isnan
564 #  define isnan(x) _GL_WARN_REAL_FLOATING_IMPL (isnan, x)
565 # endif
566 #endif
567
568
569 #if @GNULIB_SIGNBIT@
570 # if @REPLACE_SIGNBIT_USING_GCC@
571 #  undef signbit
572    /* GCC 4.0 and newer provides three built-ins for signbit.  */
573 #  define signbit(x) \
574    (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
575     sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
576     __builtin_signbitf (x))
577 # endif
578 # if @REPLACE_SIGNBIT@
579 #  undef signbit
580 extern int gl_signbitf (float arg);
581 extern int gl_signbitd (double arg);
582 extern int gl_signbitl (long double arg);
583 #  if __GNUC__ >= 2 && !__STRICT_ANSI__
584 #   if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT && !defined gl_signbitf
585 #    define gl_signbitf_OPTIMIZED_MACRO
586 #    define gl_signbitf(arg) \
587        ({ union { float _value;                                         \
588                   unsigned int _word[(sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
589                 } _m;                                                   \
590           _m._value = (arg);                                            \
591           (_m._word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1;          \
592         })
593 #   endif
594 #   if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT && !defined gl_signbitd
595 #    define gl_signbitd_OPTIMIZED_MACRO
596 #    define gl_signbitd(arg) \
597        ({ union { double _value;                                                \
598                   unsigned int _word[(sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
599                 } _m;                                                   \
600           _m._value = (arg);                                            \
601           (_m._word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1;          \
602         })
603 #   endif
604 #   if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT && !defined gl_signbitl
605 #    define gl_signbitl_OPTIMIZED_MACRO
606 #    define gl_signbitl(arg) \
607        ({ union { long double _value;                                   \
608                   unsigned int _word[(sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
609                 } _m;                                                   \
610           _m._value = (arg);                                            \
611           (_m._word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1;                \
612         })
613 #   endif
614 #  endif
615 #  define signbit(x) \
616    (sizeof (x) == sizeof (long double) ? gl_signbitl (x) : \
617     sizeof (x) == sizeof (double) ? gl_signbitd (x) : \
618     gl_signbitf (x))
619 # endif
620 #elif defined GNULIB_POSIXCHECK
621 # if defined signbit
622 _GL_WARN_REAL_FLOATING_DECL (signbit);
623 #  undef signbit
624 #  define signbit(x) _GL_WARN_REAL_FLOATING_IMPL (signbit, x)
625 # endif
626 #endif
627
628
629 #ifdef __cplusplus
630 }
631 #endif
632
633 #endif /* _GL_MATH_H */
634 #endif /* _GL_MATH_H */