#if HAVE_SNANF
+/* Returns a signalling 'float' NaN with sign bit == 0 in memory. */
+_GL_UNUSED static memory_float
+memory_positive_SNaNf ()
+{
+ return construct_memory_SNaNf (positive_NaNf ());
+}
+
+/* Returns a signalling 'float' NaN with sign bit == 1 in memory. */
+_GL_UNUSED static memory_float
+memory_negative_SNaNf ()
+{
+ return construct_memory_SNaNf (negative_NaNf ());
+}
+
+/* Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", the following functions may return a quiet NaN
+ instead. Use the functions with 'memory_' prefix if you need to avoid this.
+ See <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
+
/* Returns a signalling 'float' NaN with sign bit == 0. */
_GL_UNUSED static float
positive_SNaNf ()
{
- return construct_SNaNf (positive_NaNf ());
+ return memory_positive_SNaNf ().value;
}
/* Returns a signalling 'float' NaN with sign bit == 1. */
_GL_UNUSED static float
negative_SNaNf ()
{
- return construct_SNaNf (negative_NaNf ());
+ return memory_negative_SNaNf ().value;
}
#endif
#if HAVE_SNAND
+/* Returns a signalling 'double' NaN with sign bit == 0 in memory. */
+_GL_UNUSED static memory_double
+memory_positive_SNaNd ()
+{
+ return construct_memory_SNaNd (positive_NaNd ());
+}
+
+/* Returns a signalling 'double' NaN with sign bit == 1 in memory. */
+_GL_UNUSED static memory_double
+memory_negative_SNaNd ()
+{
+ return construct_memory_SNaNd (negative_NaNd ());
+}
+
+/* Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", the following functions may return a quiet NaN
+ instead. Use the functions with 'memory_' prefix if you need to avoid this.
+ See <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
+
/* Returns a signalling 'double' NaN with sign bit == 0. */
_GL_UNUSED static double
positive_SNaNd ()
{
- return construct_SNaNd (positive_NaNd ());
+ return memory_positive_SNaNd ().value;
}
/* Returns a signalling 'double' NaN with sign bit == 1. */
_GL_UNUSED static double
negative_SNaNd ()
{
- return construct_SNaNd (negative_NaNd ());
+ return memory_negative_SNaNd ().value;
}
#endif
#if HAVE_SNANL
+/* Returns a signalling 'long double' NaN with sign bit == 0 in memory. */
+_GL_UNUSED static memory_long_double
+memory_positive_SNaNl ()
+{
+ return construct_memory_SNaNl (positive_NaNl ());
+}
+
+/* Returns a signalling 'long double' NaN with sign bit == 1 in memory. */
+_GL_UNUSED static memory_long_double
+memory_negative_SNaNl ()
+{
+ return construct_memory_SNaNl (negative_NaNl ());
+}
+
+/* Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE is 1, the
+ following functions may return a quiet NaN instead. Use the functions
+ with 'memory_' prefix if you need to avoid this. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
+
/* Returns a signalling 'long double' NaN with sign bit == 0. */
_GL_UNUSED static long double
positive_SNaNl ()
{
- return construct_SNaNl (positive_NaNl ());
+ return memory_positive_SNaNl ().value;
}
/* Returns a signalling 'long double' NaN with sign bit == 1. */
_GL_UNUSED static long double
negative_SNaNl ()
{
- return construct_SNaNl (negative_NaNl ());
+ return memory_negative_SNaNl ().value;
}
#endif
/* 'float' = IEEE 754 single-precision
<https://en.wikipedia.org/wiki/Single-precision_floating-point_format> */
+#define NWORDS \
+ ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { float value; unsigned int word[NWORDS]; } memory_float;
+
#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
# define HAVE_SNANF 1
-_GL_UNUSED static float
-construct_SNaNf (float quiet_value)
+_GL_UNUSED static memory_float
+construct_memory_SNaNf (float quiet_value)
{
- #define NWORDS \
- ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
- typedef union { float value; unsigned int word[NWORDS]; } memory_float;
memory_float m;
m.value = quiet_value;
/* Turn the quiet NaN into a signalling NaN. */
m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
else /* NWORDS == 1 or little endian */
m.word[0] |= (unsigned int) 1;
- #undef NWORDS
- return m.value;
+ return m;
+}
+
+/* Returns a signalling 'float' NaN in memory. */
+_GL_UNUSED static memory_float
+memory_SNaNf ()
+{
+ return construct_memory_SNaNf (NaNf ());
+}
+
+_GL_UNUSED static float
+construct_SNaNf (float quiet_value)
+{
+ return construct_memory_SNaNf (quiet_value).value;
}
-/* Returns a signalling 'float' NaN. */
+/* Returns a signalling 'float' NaN.
+ Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", this function may return a quiet NaN instead.
+ Use memory_SNaNf() if you need to avoid this. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
_GL_UNUSED static float
SNaNf ()
{
- return construct_SNaNf (NaNf ());
+ return memory_SNaNf ().value;
}
#endif
+#undef NWORDS
+
/* 'double' = IEEE 754 double-precision
<https://en.wikipedia.org/wiki/Double-precision_floating-point_format> */
+#define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { double value; unsigned int word[NWORDS]; } memory_double;
+
#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
# define HAVE_SNAND 1
-_GL_UNUSED static double
-construct_SNaNd (double quiet_value)
+_GL_UNUSED static memory_double
+construct_memory_SNaNd (double quiet_value)
{
- #define NWORDS \
- ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
- typedef union { double value; unsigned int word[NWORDS]; } memory_double;
memory_double m;
m.value = quiet_value;
/* Turn the quiet NaN into a signalling NaN. */
/* Set some arbitrary mantissa bit. */
m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
|= (unsigned int) 1 << DBL_EXPBIT0_BIT;
- #undef NWORDS
- return m.value;
+ return m;
+}
+
+/* Returns a signalling 'double' NaN in memory. */
+_GL_UNUSED static memory_double
+memory_SNaNd ()
+{
+ return construct_memory_SNaNd (NaNd ());
}
-/* Returns a signalling 'double' NaN. */
+_GL_UNUSED static double
+construct_SNaNd (double quiet_value)
+{
+ return construct_memory_SNaNd (quiet_value).value;
+}
+
+/* Returns a signalling 'double' NaN.
+ Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", this function may return a quiet NaN instead.
+ Use memory_SNaNf() if you need to avoid this. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
_GL_UNUSED static double
SNaNd ()
{
- return construct_SNaNd (NaNd ());
+ return memory_SNaNd ().value;
}
#endif
+#undef NWORDS
+
/* 'long double' =
* if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE:
80-bits extended-precision, padded to 96 bits, with non-IEEE exponent
*/
+#define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+typedef union { unsigned int word[NWORDS]; long double value; }
+ memory_long_double;
+
#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
# define HAVE_SNANL 1
-_GL_UNUSED static long double
-construct_SNaNl (long double quiet_value)
+_GL_UNUSED static memory_long_double
+construct_memory_SNaNl (long double quiet_value)
{
- /* A bit pattern that is different from a Quiet NaN. With a bit of luck,
- it's a Signalling NaN. */
- #define NWORDS \
- ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
- typedef union { unsigned int word[NWORDS]; long double value; }
- memory_long_double;
memory_long_double m;
m.value = quiet_value;
#if defined __powerpc__ && LDBL_MANT_DIG == 106
m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)]
|= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
#undef HNWORDS
- #undef NWORDS
- return m.value;
+ return m;
+}
+
+/* Returns a signalling 'long double' NaN in memory. */
+_GL_UNUSED static memory_long_double
+memory_SNaNl ()
+{
+ return construct_memory_SNaNl (NaNl ());
}
-/* Returns a signalling 'long double' NaN. */
+_GL_UNUSED static long double
+construct_SNaNl (long double quiet_value)
+{
+ return construct_memory_SNaNl (quiet_value).value;
+}
+
+/* Returns a signalling 'long double' NaN.
+ Note: On 32-bit x86 processors, as well as on x86_64 processors with
+ CC="gcc -mfpmath=387", if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE is 1, this
+ function may return a quiet NaN instead. Use memory_SNaNf() if you
+ need to avoid this. See
+ <https://lists.gnu.org/archive/html/bug-gnulib/2023-10/msg00060.html>
+ for details. */
_GL_UNUSED static long double
SNaNl ()
{
- return construct_SNaNl (NaNl ());
+ return memory_SNaNl ().value;
}
#endif
+#undef NWORDS
+
#endif /* _SNAN_H */