This is a live mirror of the Perl 5 development currently hosted at
Fix NaN double to long double conversion on VMS.
authorCraig A. Berry <>
Sat, 20 Sep 2014 15:40:35 +0000 (10:40 -0500)
committerCraig A. Berry <>
Sat, 20 Sep 2014 17:43:01 +0000 (12:43 -0500)
Promotion from double to long double on VMS is apparently done via
the math routine OTS$CVT_FLOAT_T_X, which seems to do the right
thing for ordinary values, infinities, and signaling NaNs.  But
for quiet NaNs (and only on Itanium, not Alpha) it produces a
negative infinity rather than a NaN.  Oops.

So hack around that by detecting NaN in the double and explicitly
setting it in the long double.  We can't use NV_NAN because this
is the code path in Perl_sv_vcatpvfn_flags where we have not
configured long doubles but are using the "fv" long double to format


diff --git a/sv.c b/sv.c
index 53b4f8b..b22f770 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -11098,10 +11098,17 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
        long double fv;
 #  define FV_ISFINITE(x) Perl_isfinitel(x)
 #  define FV_GF PERL_PRIgldbl
+#    if defined(__VMS) && defined(__ia64) && defined(__IEEE_FLOAT)
+       /* Work around breakage in OTS$CVT_FLOAT_T_X */
+#      define NV_TO_FV(nvsv) (Perl_isnan(SvNV(nvsv)) ? LDBL_SNAN : SvNV(nvsv));
+#    else
+#      define NV_TO_FV SvNV
+#    endif
        NV fv;
 #  define FV_ISFINITE(x) Perl_isfinite((NV)(x))
 #  define FV_GF NVgf
+#  define NV_TO_FV SvNV
        STRLEN have;
        STRLEN need;
@@ -11844,7 +11851,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
-                fv = SvNV(argsv);
+                fv = NV_TO_FV(argsv);
            need = 0;
            /* frexp() (or frexpl) has some unspecified behaviour for