From: Dominic Dunlop Date: Tue, 15 Aug 2000 22:20:52 +0000 (+0200) Subject: (Retracted by #6660) X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d764f01a54c0f82174c22184bb83b9dca8be1913;p=p5sagit%2Fp5-mst-13.2.git (Retracted by #6660) Subject: [PATCH perl-current] make s?printf() produce two exponent digits where possible Message-Id: p4raw-id: //depot/perl@6645 --- diff --git a/Configure b/Configure index 2055d42..52b66cd 100755 --- a/Configure +++ b/Configure @@ -20,7 +20,7 @@ # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $ # -# Generated on Tue Aug 15 17:35:03 EET DST 2000 [metaconfig 3.0 PL70] +# Generated on Wed Aug 16 02:10:47 EET DST 2000 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.com) cat >/tmp/c1$$ <try.c <<'EOSC' +#include +int main() { + char b[10]; + exit(sprintf(b, "%0.1e", 1.2) - 5); +} +EOSC +set try +if eval $compile; then + ./try$_exe + case "$?" in + 2|3) d_printf_exp_digits=$? ;; + esac +fi +case "$d_printf_exp_digits" in +2|3) echo "Your sprintf seems to use $d_printf_exp_digits exponent digits." + ;; +*) cat <&4 +I do not understand what your sprintf is saying. +I'm guessing it uses at least 2 exponent digits. +EOM + d_printf_exp_digits=2 + ;; +esac +$rm -f try try.* + : see whether the various POSIXish _yields exist $cat >try.c < exists and * should be included. diff --git a/config_h.SH b/config_h.SH index e66e0c5..209c96f 100644 --- a/config_h.SH +++ b/config_h.SH @@ -3156,6 +3156,13 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un #define PERL_XS_APIVERSION "$xs_apiversion" #define PERL_PM_APIVERSION "$pm_apiversion" +/* PRINTF_EXP_DIGITS: + * This symbol's value is either 2 or 3, corresponding to the + * number of exponent digits produced by the system's sprintf %[FGfg] + * formats when the modulus of the exponent is 99 or less. + */ +#define PRINTF_EXP_DIGITS $d_printf_exp_digits + /* I_LIBUTIL: * This symbol, if defined, indicates that exists and * should be included. diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 9afa44d..45b2f8e 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -27,6 +27,37 @@ to be the case and the 'cc' does not seem to be the GNU C compiler =head1 Platform specific changes +=head2 printf() and sprintf() give two-digit exponent where possible + +Perl's printf() and sprintf() use the standard C library sprintf() +function to implement the floating point conversions provided by the +C<%e>, C<%f> and C<%g> formats (and their upper-case counterparts). C +library sprintf() functions vary in the number of exponent digits that +they produce in scientific notation when the modulus of the exponent +is less than one hundred: most platforms give two digits (for example, +C<1.234e-45>) while others, notably Microsoft's libraries for Windows, +give three (as in C<1.234e-045>). Previously, Perl's functions +produced results identical to the platform's underlying library +function, resulting in script portability problems. Now, on all +platforms, only two exponent digits are delivered unless more are +needed. + +Note that this change applies only to explicit conversions made by +printf() and sprintf(); implicit conversions still show the same +behavior as the underlying library function: + + print "native: ", 1234567e89, sprintf("; standardized: %e\n", 1234567e89) + +outputs + + native: 1.234567e+95; standardized: 1.234567e+95 + +on most platforms, and + + native: 1.234567e+095; standardized: 1.234567e+95 + +on the remainder. + =head1 Significant bug fixes =head1 New or Changed Diagnostics diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index a56b4a8..24dcea2 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -4444,6 +4444,10 @@ permits these unnecessary but widely-supported conversions: %O a synonym for %lo %F a synonym for %f +Conversions to scientific notation by C<%e>, C<%E>, C<%g> and C<%G> +always have a two-digit exponent unless the modulus of the exponent is +greater than 99. + Perl permits the following universally-known flags between the C<%> and the conversion letter: diff --git a/sv.c b/sv.c index ab4d6d5..80d94b5 100644 --- a/sv.c +++ b/sv.c @@ -6559,9 +6559,38 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV (void)sprintf(PL_efloatbuf, eptr, nv); RESTORE_NUMERIC_LOCAL(); } - eptr = PL_efloatbuf; elen = strlen(PL_efloatbuf); + +#if PRINTF_EXP_DIGITS == 3 /* Shorten exponent */ + if (((p = index(eptr, 'e')) || (p = index(eptr, 'E'))) && + (*++p == '+' || *p == '-') && /* Is there exponent */ + *++p == '0') { /* with leading zero? */ + DEBUG_c(PerlIO_printf(Perl_debug_log, + ">%s<: '0' at %d from start; " + "elen == %d, width == %d\n", + eptr, p-eptr, elen, width)); + Move(p+1, p, 3, char); /* Suppress leading zero */ + if (elen == width && /* Fix up padding if */ + *(p+2) == '\0') { /* necessary */ + if (!left) { + if (fill == '0') { + Move(eptr+1, eptr+2, elen-1, char); + *(eptr+1) = '0'; + } + else { + Move(eptr, eptr+1, elen, char); + *eptr = ' '; + } + } + else { + *(p+2) == ' '; *(p+3) = '\0'; + } + } + else if (elen > width) + elen--; + } +# endif break; /* SPECIAL */ @@ -8343,4 +8372,3 @@ do_clean_all(pTHXo_ SV *sv) SvFLAGS(sv) |= SVf_BREAK; SvREFCNT_dec(sv); } - diff --git a/t/op/sprintf.t b/t/op/sprintf.t index 8bb7536..e96c683 100755 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@ -197,8 +197,10 @@ __END__ >%12.4e< >1234.875< > 1.2349e+03< >%+-12.4e< >1234.875< >+1.2349e+03 < >%+12.4e< >1234.875< > +1.2349e+03< +>%+012.4e< >1234.875< >+01.2349e+03< >%+-12.4e< >-1234.875< >-1.2349e+03 < >%+12.4e< >-1234.875< > -1.2349e+03< +>%+012.4e< >-1234.875< >-01.2349e+03< >%f< >1234.875< >1234.875000< >%+f< >1234.875< >+1234.875000< >%#f< >1234.875< >1234.875000< @@ -213,8 +215,10 @@ __END__ >%8.1f< >1234.875< > 1234.9< >%+-8.1f< >1234.875< >+1234.9 < >%+8.1f< >1234.875< > +1234.9< +>%+08.1f< >1234.875< >+01234.9< >%+-8.1f< >-1234.875< >-1234.9 < >%+8.1f< >-1234.875< > -1234.9< +>%+08.1f< >-1234.875< >-01234.9< >%*.*f< >[5, 2, 12.3456]< >12.35< >%f< >0< >0.000000< >%.0f< >0< >0< @@ -252,6 +256,7 @@ __END__ >%g< >0< >0< >%13g< >1234567.89< > 1.23457e+06< >%+13g< >1234567.89< > +1.23457e+06< +>%+013g< >1234567.89< >+01.23457e+06< >%013g< >1234567.89< >001.23457e+06< >%-13g< >1234567.89< >1.23457e+06 < >%h< >''< >%h INVALID<