* doc/posix-headers/math.texi: Mention some FreeBSD and AIX bugs.
* lib/math.in.h (INFINITY): New macro.
(NAN): Replace also on FreeBSD < 8 and AIX. Use __builtin_nanf where
available.
(HUGE_VALF): Replace also on FreeBSD < 6. Use __builtin_inff where
available.
(HUGE_VAL): Replace also on FreeBSD < 6. Use __builtin_inf where
available.
(HUGE_VALL): Replace also on FreeBSD < 6. Use __builtin_infl where
available.
* tests/test-math.c: Check that INFINITY, NAN, HUGE_VALF, HUGE_VAL,
HUGE_VALL are constant expressions.
(main): Check the type of INFINITY and NAN.
+2024-08-01 Bruno Haible <bruno@clisp.org>
+
+ math: Fix INFINITY and NAN on FreeBSD and AIX.
+ * doc/posix-headers/math.texi: Mention some FreeBSD and AIX bugs.
+ * lib/math.in.h (INFINITY): New macro.
+ (NAN): Replace also on FreeBSD < 8 and AIX. Use __builtin_nanf where
+ available.
+ (HUGE_VALF): Replace also on FreeBSD < 6. Use __builtin_inff where
+ available.
+ (HUGE_VAL): Replace also on FreeBSD < 6. Use __builtin_inf where
+ available.
+ (HUGE_VALL): Replace also on FreeBSD < 6. Use __builtin_infl where
+ available.
+ * tests/test-math.c: Check that INFINITY, NAN, HUGE_VALF, HUGE_VAL,
+ HUGE_VALL are constant expressions.
+ (main): Check the type of INFINITY and NAN.
+
2024-08-01 Bruno Haible <bruno@clisp.org>
Ensure consistent effects of _LINUX_SOURCE_COMPAT.
@c https://dev.haiku-os.org/ticket/18351
Haiku 2022.
+@item
+@code{HUGE_VAL}, @code{HUGE_VALF}, @code{HUGE_VALL} are not compile time
+constants on some platforms:
+FreeBSD 5.2.
+
+@item
+@code{INFINITY} and @code{NAN} are not compile time constants
+on some platforms:
+FreeBSD 5.2, AIX 7.1.
+
+@item
+@code{INFINITY} and @code{NAN} are of type @code{double} instead of @code{float}
+on some platforms:
+FreeBSD 7.1.
+
@item
The macros @code{NAN}, @code{HUGE_VALL}, and @code{INFINITY} are not
defined on some platforms:
#endif
+/* Ensure that INFINITY is a constant expression, of type 'float'. */
+#if !defined INFINITY || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX
+# undef INFINITY
+# if defined __GNUC__ || defined __clang__
+# define INFINITY (__builtin_inff ())
+# else
+# define INFINITY (1.0f / 0.0f)
+# endif
+#endif
+
/* POSIX allows platforms that don't support NAN. But all major
machines in the past 15 years have supported something close to
IEEE NaN, so we define this unconditionally. We also must define
it on platforms like Solaris 10, where NAN is present but defined
- as a function pointer rather than a floating point constant. */
-#if !defined NAN || @REPLACE_NAN@
+ as a function pointer rather than a floating point constant.
+ Also ensure that it is a constant expression, of type 'float'. */
+#if !defined NAN || @REPLACE_NAN@ || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX
# if !GNULIB_defined_NAN
# undef NAN
/* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler
return zero / zero;
}
# define NAN (_NaN())
+# elif defined __GNUC__ || defined __clang__
+# define NAN (__builtin_nanf (""))
# else
# define NAN (0.0f / 0.0f)
# endif
#endif
/* HUGE_VALF is a 'float' Infinity. */
-#ifndef HUGE_VALF
+#if !defined HUGE_VALF || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VALF
# if defined _MSC_VER
/* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f. */
# define HUGE_VALF (1e25f * 1e25f)
+# elif defined __GNUC__ || defined __clang__
+# define HUGE_VALF (__builtin_inff ())
# else
# define HUGE_VALF (1.0f / 0.0f)
# endif
#endif
/* HUGE_VAL is a 'double' Infinity. */
-#ifndef HUGE_VAL
+#if !defined HUGE_VAL || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VAL
# if defined _MSC_VER
/* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0. */
# define HUGE_VAL (1e250 * 1e250)
+# elif defined __GNUC__ || defined __clang__
+# define HUGE_VAL (__builtin_inf ())
# else
# define HUGE_VAL (1.0 / 0.0)
# endif
#endif
/* HUGE_VALL is a 'long double' Infinity. */
-#ifndef HUGE_VALL
+#if !defined HUGE_VALL || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VALL
# if defined _MSC_VER
/* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L. */
# define HUGE_VALL (1e250L * 1e250L)
+# elif defined __GNUC__ || defined __clang__
+# define HUGE_VALL (__builtin_infl ())
# else
# define HUGE_VALL (1.0L / 0.0L)
# endif
#include <math.h>
+#ifndef INFINITY
+# error INFINITY should be defined, added in ISO C 99
+choke me
+#endif
+
#ifndef NAN
-# error NAN should be defined
+# error NAN should be defined, added in ISO C 99
choke me
#endif
choke me
#endif
-#if 0
+/* Check that INFINITY expands into a constant expression. */
+float in = INFINITY;
+
/* Check that NAN expands into a constant expression. */
-static float n = NAN;
-#endif
+float na = NAN;
+
+/* Check that HUGE_VALF expands into a constant expression. */
+float hf = HUGE_VALF;
+
+/* Check that HUGE_VAL expands into a constant expression. */
+double hd = HUGE_VAL;
+
+/* Check that HUGE_VALL expands into a constant expression. */
+long double hl = HUGE_VALL;
#include <limits.h>
int
main (void)
{
- double d = NAN;
+ double d;
double zero = 0.0;
- ASSERT (!numeric_equald (d, d));
- d = HUGE_VAL;
- ASSERT (numeric_equald (d, 1.0 / zero));
+ /* Check that INFINITY is a float. */
+ ASSERT (sizeof (INFINITY) == sizeof (float));
+
+ /* Check that NAN is a float. */
+ ASSERT (sizeof (NAN) == sizeof (float));
+ /* Check the value of NAN. */
+ d = NAN;
+ ASSERT (!numeric_equald (d, d));
+
+ /* Check the value of HUGE_VALF. */
ASSERT (numeric_equalf (HUGE_VALF, HUGE_VALF + HUGE_VALF));
+ /* Check the value of HUGE_VAL. */
+ d = HUGE_VAL;
+ ASSERT (numeric_equald (d, 1.0 / zero));
ASSERT (numeric_equald (HUGE_VAL, HUGE_VAL + HUGE_VAL));
+ /* Check the value of HUGE_VALL. */
ASSERT (numeric_equall (HUGE_VALL, HUGE_VALL + HUGE_VALL));
/* Check the value of FP_ILOGB0. */