# include "config.h"
#endif
-#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(_STDC_C99)
+/* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
+ * because the __STDC_VERSION__ became a thing only with C90. Therefore,
+ * with gcc, HAS_C99 will never become true as long as we use -std=c89.
+
+ * NOTE 2: headers lie. Do not expect that if HAS_C99 gets to be true,
+ * all the C99 features are there and are correct. */
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ defined(_STDC_C99)
# define HAS_C99 1
#endif
# include <ieeefp.h>
#endif
-/* We need Perl_isfinitel (ends with ell) (if available) even when
- * not USE_LONG_DOUBLE because the printf code (sv_catpvfn_flags)
- * needs that. */
-#if defined(HAS_LONG_DOUBLE) && !defined(Perl_isfinitel)
-/* If isfinite() is a macro and looks like we have C99,
- * we assume it's the type-aware C99 isfinite(). */
-# if defined(isfinite) && defined(HAS_C99)
-# define Perl_isfinitel(x) isfinite(x)
-# elif defined(HAS_ISFINITEL)
-# define Perl_isfinitel(x) isfinitel(x)
-# elif defined(HAS_FINITEL)
-# define Perl_isfinitel(x) finitel(x)
-# elif defined(LDBL_MAX)
-# define Perl_isfinitel(x) ((x) <= LDBL_MAX && (x) >= -LDBL_MAX)
-# endif
-#endif
-
#ifdef USE_LONG_DOUBLE
# ifdef I_SUNMATH
# include <sunmath.h>
# define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
# endif
# endif
-# ifdef Perl_isfinitel
+# ifndef Perl_isfinite
# define Perl_isfinite(x) Perl_isfinitel(x)
# endif
#else
# define Perl_isfinite(x) isfinite(x)
# elif defined(HAS_FINITE)
# define Perl_isfinite(x) finite(x)
-# elif defined(DBL_MAX)
-# define Perl_isfinite(x) ((x) <= DBL_MAX && (x) >= -DBL_MAX)
# endif
# endif
#endif
#ifndef Perl_isfinite
# if defined(HAS_ISFINITE) && !defined(isfinite)
-# define Perl_isfinite(x) isfinite((double)x)
+# define Perl_isfinite(x) isfinite((double)(x))
# elif defined(HAS_FINITE)
-# define Perl_isfinite(x) finite((double)x)
+# define Perl_isfinite(x) finite((double)(x))
# elif defined(Perl_fp_class_finite)
# define Perl_isfinite(x) Perl_fp_class_finite(x)
# else
-/* NaN*0 is NaN, [+-]Inf*0 is NaN, zero for anything else. */
+/* For the infinities the multiplication returns nan,
+ * for the nan the multiplication also returns nan,
+ * for everything else (that is, finite) zero should be returned. */
# define Perl_isfinite(x) (((x) * 0) == 0)
# endif
#endif
# endif
#endif
+/* We need Perl_isfinitel (ends with ell) (if available) even when
+ * not USE_LONG_DOUBLE because the printf code (sv_catpvfn_flags)
+ * needs that. */
+#if defined(HAS_LONG_DOUBLE) && !defined(Perl_isfinitel)
+/* If isfinite() is a macro and looks like we have C99,
+ * we assume it's the type-aware C99 isfinite(). */
+# if defined(HAS_ISFINITE) && defined(isfinite) && defined(HAS_C99)
+# define Perl_isfinitel(x) isfinite(x)
+# elif defined(HAS_ISFINITEL)
+# define Perl_isfinitel(x) isfinitel(x)
+# elif defined(HAS_FINITEL)
+# define Perl_isfinitel(x) finitel(x)
+# elif defined(HAS_INFL) && defined(HAS_NANL)
+# define Perl_isfinitel(x) !(isinfl(x)||isnanl(x))
+# else
+# define Perl_isfinitel(x) ((x) * 0 == 0) /* See Perl_isfinite. */
+# endif
+#endif
+
/* The default is to use Perl's own atof() implementation (in numeric.c).
* Usually that is the one to use but for some platforms (e.g. UNICOS)
* it is however best to use the native implementation of atof.
# if !defined(NV_INF) && defined(HUGE_VAL)
# define NV_INF HUGE_VAL
# endif
-# ifndef NV_NAN
-# define NV_NAN (NV_INF-NV_INF)
-# endif
+/* For WIN32 the best NV_NAN is the __PL_nan_u trick, see below.
+ * There is no supported way of getting the NAN across all the crts. */
#endif
/* If you are thinking of using HUGE_VAL for infinity, or using
#if !defined(NV_NAN)
# define NV_NAN ((NV)0.0/0.0) /* Some compilers will warn. */
#endif
+/* Do NOT try doing NV_NAN based on NV_INF and trying (NV_INF-NV_INF).
+ * Though IEEE-754-logically correct, some compilers (like Visual C 2003)
+ * falsely misoptimize that to zero (x-x is zero, right?) */
#ifndef __cplusplus
# if !defined(WIN32) && !defined(VMS)