summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2015-02-03 18:20:40 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2015-02-04 08:47:22 -0500
commita57d3d4daf4971adfdd5495458434fbba9257efe (patch)
treeb586809f5ecf86ee5bb6d2d405b6d00f8cdb45c4 /sv.c
parentdb0562f0f6a78b868db85f5ec10f73940b254224 (diff)
downloadperl-a57d3d4daf4971adfdd5495458434fbba9257efe.tar.gz
Prefer NV instead of long double.
Background: sprintf aka sv_vcatpvn_flags uses a long double for floating point values whenever has-long-double, not only when use-long-double. The (only?) reason for this is being able to (perlio) printf long doubles from XS, even if no use-long-double. (see ext/XS-APItest/t/printf.t) Instead of casting the long double (explicitly or implicitly), try keeping also an NV in sync, and using it. Could probably use the NV even more, but trying to stay minimal given the impending 5.22.
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/sv.c b/sv.c
index cf888fd110..0160443a48 100644
--- a/sv.c
+++ b/sv.c
@@ -11351,6 +11351,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
#ifndef FV_ISFINITE
# define FV_ISFINITE(x) Perl_isfinite((NV)(x))
#endif
+ NV nv;
STRLEN have;
STRLEN need;
STRLEN gap;
@@ -12094,19 +12095,25 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
#ifdef USE_QUADMATH
fv = intsize == 'q' ?
va_arg(*args, NV) : va_arg(*args, double);
+ nv = fv;
#elif LONG_DOUBLESIZE > DOUBLESIZE
- if (intsize == 'q')
+ if (intsize == 'q') {
fv = va_arg(*args, long double);
- else
- NV_TO_FV(va_arg(*args, double), fv);
+ nv = fv;
+ } else {
+ nv = va_arg(*args, double);
+ NV_TO_FV(nv, fv);
+ }
#else
- fv = va_arg(*args, double);
+ nv = va_arg(*args, double);
+ fv = nv;
#endif
}
else
{
if (!infnan) SvGETMAGIC(argsv);
- NV_TO_FV(SvNV_nomg(argsv), fv);
+ nv = SvNV_nomg(argsv);
+ NV_TO_FV(nv, fv);
}
need = 0;
@@ -12253,7 +12260,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
goto float_converted;
}
} else if ( c == 'f' && !precis ) {
- if ((eptr = F0convert(fv, ebuf + sizeof ebuf, &elen)))
+ if ((eptr = F0convert(nv, ebuf + sizeof ebuf, &elen)))
break;
}
}
@@ -12281,10 +12288,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
* should be output as 0x0.0000000000001p-1022 to
* match its internal structure. */
- /* Note: fv can be (and often is) long double.
- * Here it is explicitly cast to NV. */
- vend = S_hextract(aTHX_ (NV)fv, &exponent, vhex, NULL);
- S_hextract(aTHX_ (NV)fv, &exponent, vhex, vend);
+ vend = S_hextract(aTHX_ nv, &exponent, vhex, NULL);
+ S_hextract(aTHX_ nv, &exponent, vhex, vend);
#if NVSIZE > DOUBLESIZE
# ifdef HEXTRACT_HAS_IMPLICIT_BIT
@@ -12442,7 +12447,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
}
}
else {
- elen = S_infnan_2pv(fv, PL_efloatbuf, PL_efloatsize, plus);
+ elen = S_infnan_2pv(nv, PL_efloatbuf, PL_efloatsize, plus);
if (elen) {
/* Not affecting infnan output: precision, alt, fill. */
if (elen < width) {
@@ -12518,7 +12523,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
if (!qfmt)
Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", ptr);
elen = quadmath_snprintf(PL_efloatbuf, PL_efloatsize,
- qfmt, fv);
+ qfmt, nv);
if ((IV)elen == -1)
Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s|'", qfmt);
if (qfmt != ptr)