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