In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/a57d3d4daf4971adfdd5495458434fbba9257efe?hp=db0562f0f6a78b868db85f5ec10f73940b254224>
- Log ----------------------------------------------------------------- commit a57d3d4daf4971adfdd5495458434fbba9257efe Author: Jarkko Hietaniemi <[email protected]> Date: Tue Feb 3 18:20:40 2015 -0500 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. ----------------------------------------------------------------------- Summary of changes: sv.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/sv.c b/sv.c index cf888fd..0160443 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) -- Perl5 Master Repository
