diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-11-28 22:56:29 -0500 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2015-11-29 18:26:04 +0000 |
commit | 9677f0ce70c0d066e562e5e9f4a2e607f90bc0a7 (patch) | |
tree | 1a37fea0a99343971a1268292fc46e59cb499ea3 | |
parent | 4b0ae52dee99f81c20d3a8d6b59c926e54eb8fa3 (diff) | |
download | perl-9677f0ce70c0d066e562e5e9f4a2e607f90bc0a7.tar.gz |
hexfp: printf %.13a 0.0
(cherry picked from commit 798a7a50ba821b0294cbf03dc1e274fa128084db)
-rw-r--r-- | sv.c | 37 | ||||
-rw-r--r-- | t/op/sprintf2.t | 6 |
2 files changed, 30 insertions, 13 deletions
@@ -12298,6 +12298,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p U8* v = vhex; /* working pointer to vhex */ U8* vend; /* pointer to one beyond last digit of vhex */ U8* vfnz = NULL; /* first non-zero */ + U8* vlnz = NULL; /* last non-zero */ const bool lower = (c == 'a'); /* At output the values of vhex (up to vend) will * be mapped through the xdig to get the actual @@ -12305,6 +12306,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p const char* xdig = PL_hexdigit; int zerotail = 0; /* how many extra zeros to append */ int exponent = 0; /* exponent of the floating point input */ + bool hexradix = FALSE; /* should we output the radix */ /* XXX: denormals, NaN, Inf. * @@ -12353,8 +12355,6 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } if (vfnz) { - U8* vlnz = NULL; /* The last non-zero. */ - /* Find the last non-zero xdigit. */ for (v = vend - 1; v >= vhex; v--) { if (*v) { @@ -12414,9 +12414,24 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p v = vhex; *p++ = xdig[*v++]; - /* The radix is always output after the first - * non-zero xdigit, or if precis, or if alt. */ - if (vfnz < vlnz || precis > 0 || alt) { + /* If there are non-zero xdigits, the radix + * is output after the first one. */ + if (vfnz < vlnz) { + hexradix = TRUE; + } + } + else { + *p++ = '0'; + exponent = 0; + zerotail = precis; + } + + /* The radix is always output if precis, or if alt. */ + if (precis > 0 || alt) { + hexradix = TRUE; + } + + if (hexradix) { #ifndef USE_LOCALE_NUMERIC *p++ = '.'; #else @@ -12432,17 +12447,17 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p } RESTORE_LC_NUMERIC(); #endif - } + } + if (vlnz) { while (v <= vlnz) *p++ = xdig[*v++]; - - while (zerotail--) - *p++ = '0'; } - else { + + if (zerotail > 0) { + while (zerotail--) { *p++ = '0'; - exponent = 0; + } } elen = p - PL_efloatbuf; diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t index 1f0c515d3d..48986f0e06 100644 --- a/t/op/sprintf2.t +++ b/t/op/sprintf2.t @@ -69,6 +69,7 @@ if ($Config{nvsize} == 8 && [ '%.13a', '1', '0x1.0000000000000p+0' ], [ '%.13a', '-1', '-0x1.0000000000000p+0' ], + [ '%.13a', '0', '0x0.0000000000000p+0' ], [ '%30a', '3.14', ' 0x1.91eb851eb851fp+1' ], [ '%-30a', '3.14', '0x1.91eb851eb851fp+1 ' ], @@ -246,7 +247,7 @@ if ($Config{nvsize} == 8 && print "# no hexfloat tests\n"; } -plan tests => 1408 + ($Q ? 0 : 12) + @hexfloat + 8; +plan tests => 1408 + ($Q ? 0 : 12) + @hexfloat + 9; use strict; use Config; @@ -682,8 +683,9 @@ SKIP: { } SKIP: { - skip("negative zero not available\n", 2) + skip("negative zero not available\n", 3) unless sprintf('%+f', -0.0) =~ /^-0/; is(sprintf("%a", -0.0), "-0x0p+0", "negative zero"); is(sprintf("%+a", -0.0), "-0x0p+0", "negative zero"); + is(sprintf("%.13a", -0.0), "-0x0.0000000000000p+0", "negative zero"); } |