1 /* A GNU-like <math.h>.
3 Copyright (C) 2002-2003, 2007-2010 Free Software Foundation, Inc.
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.
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.
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/>. */
21 @PRAGMA_SYSTEM_HEADER@
24 /* The include_next requires a split double-inclusion guard. */
25 #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
31 /* The definition of _GL_ARG_NONNULL is copied here. */
33 /* The definition of _GL_WARN_ON_USE is copied here. */
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) \
41 rpl_ ## func ## f (float f) \
46 rpl_ ## func ## d (double d) \
51 rpl_ ## func ## l (long double l) \
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))
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@
79 /* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0. */
84 static float zero = 0.0f;
89 # define NAN (0.0f / 0.0f)
93 /* Solaris 10 defines HUGE_VAL, but as a function pointer rather
94 than a floating point constant. */
95 #if @REPLACE_HUGE_VAL@
97 # define HUGE_VAL (1.0 / 0.0)
104 If x finite and nonzero: 0.5 <= |mantissa| < 1.0.
105 If x is zero: mantissa = x, exp = 0.
106 If x is infinite or NaN: mantissa = x, exp unspecified.
107 Store exp in *EXPPTR and return mantissa. */
110 # define frexp rpl_frexp
111 extern double frexp (double x, int *expptr) _GL_ARG_NONNULL ((2));
113 #elif defined GNULIB_POSIXCHECK
115 /* Assume frexp is always declared. */
116 _GL_WARN_ON_USE (frexp, "frexp is unportable - "
117 "use gnulib module frexp for portability");
122 # if !@HAVE_DECL_LOGB@
123 extern double logb (double x);
125 #elif defined GNULIB_POSIXCHECK
127 # if HAVE_RAW_DECL_LOGB
128 _GL_WARN_ON_USE (logb, "logb is unportable - "
129 "use gnulib module logb for portability");
135 # if !@HAVE_ACOSL@ || !@HAVE_DECL_ACOSL@
136 extern long double acosl (long double x);
138 #elif defined GNULIB_POSIXCHECK
140 # if HAVE_RAW_DECL_ACOSL
141 _GL_WARN_ON_USE (acosl, "acosl is unportable - "
142 "use gnulib module mathl for portability");
148 # if !@HAVE_ASINL@ || !@HAVE_DECL_ASINL@
149 extern long double asinl (long double x);
151 #elif defined GNULIB_POSIXCHECK
153 # if HAVE_RAW_DECL_ASINL
154 _GL_WARN_ON_USE (asinl, "asinl is unportable - "
155 "use gnulib module mathl for portability");
161 # if !@HAVE_ATANL@ || !@HAVE_DECL_ATANL@
162 extern long double atanl (long double x);
164 #elif defined GNULIB_POSIXCHECK
166 # if HAVE_RAW_DECL_ATANL
167 _GL_WARN_ON_USE (atanl, "atanl is unportable - "
168 "use gnulib module mathl for portability");
175 # define ceilf rpl_ceilf
176 extern float ceilf (float x);
178 #elif defined GNULIB_POSIXCHECK
180 # if HAVE_RAW_DECL_CEILF
181 _GL_WARN_ON_USE (ceilf, "ceilf is unportable - "
182 "use gnulib module ceilf for portability");
188 # define ceill rpl_ceill
189 extern long double ceill (long double x);
191 #elif defined GNULIB_POSIXCHECK
193 # if HAVE_RAW_DECL_CEILL
194 _GL_WARN_ON_USE (ceill, "ceill is unportable - "
195 "use gnulib module ceill for portability");
203 # define cosl rpl_cosl
205 # if !@HAVE_COSL@ || !@HAVE_DECL_COSL@
206 extern long double cosl (long double x);
208 #elif defined GNULIB_POSIXCHECK
210 # if HAVE_RAW_DECL_COSL
211 _GL_WARN_ON_USE (cosl, "cosl is unportable - "
212 "use gnulib module mathl for portability");
218 # if !@HAVE_EXPL@ || !@HAVE_DECL_EXPL@
219 extern long double expl (long double x);
221 #elif defined GNULIB_POSIXCHECK
223 # if HAVE_RAW_DECL_EXPL
224 _GL_WARN_ON_USE (expl, "expl is unportable - "
225 "use gnulib module mathl for portability");
231 # if @REPLACE_FLOORF@
232 # define floorf rpl_floorf
233 extern float floorf (float x);
235 #elif defined GNULIB_POSIXCHECK
237 # if HAVE_RAW_DECL_FLOORF
238 _GL_WARN_ON_USE (floorf, "floorf is unportable - "
239 "use gnulib module floorf for portability");
244 # if @REPLACE_FLOORL@
245 # define floorl rpl_floorl
246 extern long double floorl (long double x);
248 #elif defined GNULIB_POSIXCHECK
250 # if HAVE_RAW_DECL_FLOORL
251 _GL_WARN_ON_USE (floorl, "floorl is unportable - "
252 "use gnulib module floorl for portability");
260 If x finite and nonzero: 0.5 <= |mantissa| < 1.0.
261 If x is zero: mantissa = x, exp = 0.
262 If x is infinite or NaN: mantissa = x, exp unspecified.
263 Store exp in *EXPPTR and return mantissa. */
264 #if @GNULIB_FREXPL@ && @REPLACE_FREXPL@
265 # define frexpl rpl_frexpl
267 #if (@GNULIB_FREXPL@ && @REPLACE_FREXPL@) || !@HAVE_DECL_FREXPL@
268 extern long double frexpl (long double x, int *expptr) _GL_ARG_NONNULL ((2));
270 #if !@GNULIB_FREXPL@ && defined GNULIB_POSIXCHECK
272 # if HAVE_RAW_DECL_FREXPL
273 _GL_WARN_ON_USE (frexpl, "frexpl is unportable - "
274 "use gnulib module frexpl for portability");
279 /* Return x * 2^exp. */
280 #if @GNULIB_LDEXPL@ && @REPLACE_LDEXPL@
281 # define ldexpl rpl_ldexpl
283 #if (@GNULIB_LDEXPL@ && @REPLACE_LDEXPL@) || !@HAVE_DECL_LDEXPL@
284 extern long double ldexpl (long double x, int exp);
286 #if !@GNULIB_LDEXPL@ && defined GNULIB_POSIXCHECK
288 # if HAVE_RAW_DECL_LDEXPL
289 _GL_WARN_ON_USE (ldexpl, "ldexpl is unportable - "
290 "use gnulib module ldexpl for portability");
298 # define logl rpl_logl
300 # if !@HAVE_LOGL@ || !@HAVE_DECL_LOGL@
301 extern long double logl (long double x);
303 #elif defined GNULIB_POSIXCHECK
305 # if HAVE_RAW_DECL_LOGL
306 _GL_WARN_ON_USE (logl, "logl is unportable - "
307 "use gnulib module mathl for portability");
313 # if @REPLACE_ROUNDF@
315 # define roundf rpl_roundf
316 extern float roundf (float x);
318 #elif defined GNULIB_POSIXCHECK
320 # if HAVE_RAW_DECL_ROUNDF
321 _GL_WARN_ON_USE (roundf, "roundf is unportable - "
322 "use gnulib module roundf for portability");
329 # define round rpl_round
330 extern double round (double x);
332 #elif defined GNULIB_POSIXCHECK
334 # if HAVE_RAW_DECL_ROUND
335 _GL_WARN_ON_USE (round, "round is unportable - "
336 "use gnulib module round for portability");
341 # if @REPLACE_ROUNDL@
343 # define roundl rpl_roundl
344 extern long double roundl (long double x);
346 #elif defined GNULIB_POSIXCHECK
348 # if HAVE_RAW_DECL_ROUNDL
349 _GL_WARN_ON_USE (roundl, "roundl is unportable - "
350 "use gnulib module roundl for portability");
358 # define sinl rpl_sinl
360 # if !@HAVE_SINL@ || !@HAVE_DECL_SINL@
361 extern long double sinl (long double x);
363 #elif defined GNULIB_POSIXCHECK
365 # if HAVE_RAW_DECL_SINL
366 _GL_WARN_ON_USE (sinl, "sinl is unportable - "
367 "use gnulib module mathl for portability");
373 # if !@HAVE_SQRTL@ || !@HAVE_DECL_SQRTL@
374 extern long double sqrtl (long double x);
376 #elif defined GNULIB_POSIXCHECK
378 # if HAVE_RAW_DECL_SQRTL
379 _GL_WARN_ON_USE (sqrtl, "sqrtl is unportable - "
380 "use gnulib module mathl for portability");
386 # if !@HAVE_TANL@ || !@HAVE_DECL_TANL@
387 extern long double tanl (long double x);
389 #elif defined GNULIB_POSIXCHECK
391 # if HAVE_RAW_DECL_TANL
392 _GL_WARN_ON_USE (tanl, "tanl is unportable - "
393 "use gnulib module mathl for portability");
399 # if !@HAVE_DECL_TRUNCF@
400 # define truncf rpl_truncf
401 extern float truncf (float x);
403 #elif defined GNULIB_POSIXCHECK
405 # if HAVE_RAW_DECL_TRUNCF
406 _GL_WARN_ON_USE (truncf, "truncf is unportable - "
407 "use gnulib module truncf for portability");
412 # if !@HAVE_DECL_TRUNC@
413 # define trunc rpl_trunc
414 extern double trunc (double x);
416 #elif defined GNULIB_POSIXCHECK
418 # if HAVE_RAW_DECL_TRUNC
419 _GL_WARN_ON_USE (trunc, "trunc is unportable - "
420 "use gnulib module trunc for portability");
425 # if @REPLACE_TRUNCL@
427 # define truncl rpl_truncl
428 extern long double truncl (long double x);
430 #elif defined GNULIB_POSIXCHECK
432 # if HAVE_RAW_DECL_TRUNCL
433 _GL_WARN_ON_USE (truncl, "truncl is unportable - "
434 "use gnulib module truncl for portability");
439 #if @GNULIB_ISFINITE@
440 # if @REPLACE_ISFINITE@
441 extern int gl_isfinitef (float x);
442 extern int gl_isfinited (double x);
443 extern int gl_isfinitel (long double x);
445 # define isfinite(x) \
446 (sizeof (x) == sizeof (long double) ? gl_isfinitel (x) : \
447 sizeof (x) == sizeof (double) ? gl_isfinited (x) : \
450 #elif defined GNULIB_POSIXCHECK
451 # if defined isfinite
452 _GL_WARN_REAL_FLOATING_DECL (isfinite);
454 # define isfinite(x) _GL_WARN_REAL_FLOATING_IMPL (isfinite, x)
461 extern int gl_isinff (float x);
462 extern int gl_isinfd (double x);
463 extern int gl_isinfl (long double x);
466 (sizeof (x) == sizeof (long double) ? gl_isinfl (x) : \
467 sizeof (x) == sizeof (double) ? gl_isinfd (x) : \
470 #elif defined GNULIB_POSIXCHECK
472 _GL_WARN_REAL_FLOATING_DECL (isinf);
474 # define isinf(x) _GL_WARN_REAL_FLOATING_IMPL (isinf, x)
480 /* Test for NaN for 'float' numbers. */
482 /* The original <math.h> included above provides a declaration of isnan macro
483 or (older) isnanf function. */
485 /* GCC 4.0 and newer provides three built-ins for isnan. */
487 # define isnanf(x) __builtin_isnanf ((float)(x))
490 # define isnanf(x) isnan ((float)(x))
493 /* Test whether X is a NaN. */
495 # define isnanf rpl_isnanf
496 extern int isnanf (float x);
501 /* Test for NaN for 'double' numbers.
502 This function is a gnulib extension, unlike isnan() which applied only
503 to 'double' numbers earlier but now is a type-generic macro. */
505 /* The original <math.h> included above provides a declaration of isnan macro. */
507 /* GCC 4.0 and newer provides three built-ins for isnan. */
509 # define isnand(x) __builtin_isnan ((double)(x))
512 # define isnand(x) isnan ((double)(x))
515 /* Test whether X is a NaN. */
517 # define isnand rpl_isnand
518 extern int isnand (double x);
523 /* Test for NaN for 'long double' numbers. */
525 /* The original <math.h> included above provides a declaration of isnan macro or (older) isnanl function. */
527 /* GCC 4.0 and newer provides three built-ins for isnan. */
529 # define isnanl(x) __builtin_isnanl ((long double)(x))
532 # define isnanl(x) isnan ((long double)(x))
535 /* Test whether X is a NaN. */
537 # define isnanl rpl_isnanl
538 extern int isnanl (long double x);
542 /* This must come *after* the snippets for GNULIB_ISNANF and GNULIB_ISNANL! */
545 /* We can't just use the isnanf macro (e.g.) as exposed by
546 isnanf.h (e.g.) here, because those may end up being macros
547 that recursively expand back to isnan. So use the gnulib
548 replacements for them directly. */
549 # if @HAVE_ISNANF@ && __GNUC__ >= 4
550 # define gl_isnan_f(x) __builtin_isnan ((float)(x))
552 extern int rpl_isnanf (float x);
553 # define gl_isnan_f(x) rpl_isnanf (x)
555 # if @HAVE_ISNAND@ && __GNUC__ >= 4
556 # define gl_isnan_d(x) __builtin_isnan ((double)(x))
558 extern int rpl_isnand (double x);
559 # define gl_isnan_d(x) rpl_isnand (x)
561 # if @HAVE_ISNANL@ && __GNUC__ >= 4
562 # define gl_isnan_l(x) __builtin_isnan ((long double)(x))
564 extern int rpl_isnanl (long double x);
565 # define gl_isnan_l(x) rpl_isnanl (x)
569 (sizeof (x) == sizeof (long double) ? gl_isnan_l (x) : \
570 sizeof (x) == sizeof (double) ? gl_isnan_d (x) : \
573 #elif defined GNULIB_POSIXCHECK
575 _GL_WARN_REAL_FLOATING_DECL (isnan);
577 # define isnan(x) _GL_WARN_REAL_FLOATING_IMPL (isnan, x)
583 # if @REPLACE_SIGNBIT_USING_GCC@
585 /* GCC 4.0 and newer provides three built-ins for signbit. */
586 # define signbit(x) \
587 (sizeof (x) == sizeof (long double) ? __builtin_signbitl (x) : \
588 sizeof (x) == sizeof (double) ? __builtin_signbit (x) : \
589 __builtin_signbitf (x))
591 # if @REPLACE_SIGNBIT@
593 extern int gl_signbitf (float arg);
594 extern int gl_signbitd (double arg);
595 extern int gl_signbitl (long double arg);
596 # if __GNUC__ >= 2 && !__STRICT_ANSI__
597 # if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT && !defined gl_signbitf
598 # define gl_signbitf_OPTIMIZED_MACRO
599 # define gl_signbitf(arg) \
600 ({ union { float _value; \
601 unsigned int _word[(sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
604 (_m._word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1; \
607 # if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT && !defined gl_signbitd
608 # define gl_signbitd_OPTIMIZED_MACRO
609 # define gl_signbitd(arg) \
610 ({ union { double _value; \
611 unsigned int _word[(sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
614 (_m._word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1; \
617 # if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT && !defined gl_signbitl
618 # define gl_signbitl_OPTIMIZED_MACRO
619 # define gl_signbitl(arg) \
620 ({ union { long double _value; \
621 unsigned int _word[(sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)]; \
624 (_m._word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1; \
628 # define signbit(x) \
629 (sizeof (x) == sizeof (long double) ? gl_signbitl (x) : \
630 sizeof (x) == sizeof (double) ? gl_signbitd (x) : \
633 #elif defined GNULIB_POSIXCHECK
635 _GL_WARN_REAL_FLOATING_DECL (signbit);
637 # define signbit(x) _GL_WARN_REAL_FLOATING_IMPL (signbit, x)
646 #endif /* _GL_MATH_H */
647 #endif /* _GL_MATH_H */