(Retracted by #6660)
Dominic Dunlop [Tue, 15 Aug 2000 22:20:52 +0000 (00:20 +0200)]
Subject: [PATCH perl-current] make s?printf() produce two exponent digits where possible
Message-Id: <p04320403b5bf4c32d381@[192.168.1.4]>

p4raw-id: //depot/perl@6645

Configure
Porting/Glossary
Porting/config.sh
Porting/config_H
config_h.SH
pod/perldelta.pod
pod/perlfunc.pod
sv.c
t/op/sprintf.t

index 2055d42..52b66cd 100755 (executable)
--- 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$$ <<EOF
@@ -455,6 +455,7 @@ d_pause=''
 d_pipe=''
 d_poll=''
 d_portable=''
+d_printf_exp_digits=''
 d_old_pthread_create_joinable=''
 old_pthread_create_joinable=''
 d_pthread_yield=''
@@ -10479,6 +10480,34 @@ eval $inlibc
 set poll d_poll
 eval $inlibc
 
+echo " "
+echo "Checking how many exponent digits your sprintf formats use..."
+$cat >try.c <<'EOSC'
+#include <stdio.h> 
+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 <<EOM >&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 <<EOP
@@ -15542,6 +15571,7 @@ d_phostname='$d_phostname'
 d_pipe='$d_pipe'
 d_poll='$d_poll'
 d_portable='$d_portable'
+d_printf_exp_digits='$d_printf_exp_digits'
 d_pthread_yield='$d_pthread_yield'
 d_pwage='$d_pwage'
 d_pwchange='$d_pwchange'
index f289baa..8099ea2 100644 (file)
@@ -1118,6 +1118,11 @@ d_PRIi64 (quadfio.U):
        This variable conditionally defines the PERL_PRIi64 symbol, which
        indiciates that stdio has a symbol to print 64-bit decimal numbers.
 
+d_printf_exp_digits (d_printfed.U):
+       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.
+
 d_PRIo64 (quadfio.U):
        This variable conditionally defines the PERL_PRIo64 symbol, which
        indiciates that stdio has a symbol to print 64-bit octal numbers.
index b400739..1d7e0d5 100644 (file)
@@ -8,7 +8,7 @@
 
 # Package name      : perl5
 # Source directory  : /m/fs/work/work/permanent/perl/pp4/perl
-# Configuration time: Tue Aug 15 18:22:31 EET DST 2000
+# Configuration time: Wed Aug 16 02:27:51 EET DST 2000
 # Configured by     : jhi
 # Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
 
@@ -60,7 +60,7 @@ ccflags_uselargefiles=''
 ccsymbols='__alpha=1 __LANGUAGE_C__=1 __osf__=1 __unix__=1 _LONGLONG=1 _SYSTYPE_BSD=1 SYSTYPE_BSD=1 unix=1'
 cf_by='jhi'
 cf_email='yourname@yourhost.yourplace.com'
-cf_time='Tue Aug 15 18:22:31 EET DST 2000'
+cf_time='Wed Aug 16 02:27:51 EET DST 2000'
 charsize='1'
 chgrp=''
 chmod=''
@@ -260,6 +260,7 @@ d_phostname='undef'
 d_pipe='define'
 d_poll='define'
 d_portable='define'
+d_printf_exp_digits='2'
 d_pthread_yield='undef'
 d_pwage='undef'
 d_pwchange='undef'
index a4b4d21..dddfdda 100644 (file)
@@ -17,7 +17,7 @@
 /*
  * Package name      : perl5
  * Source directory  : /m/fs/work/work/permanent/perl/pp4/perl
- * Configuration time: Tue Aug 15 18:22:31 EET DST 2000
+ * Configuration time: Wed Aug 16 02:27:51 EET DST 2000
  * Configured by     : jhi
  * Target system     : osf1 alpha.hut.fi v4.0 878 alpha 
  */
 #define PERL_XS_APIVERSION "5.7.0"
 #define PERL_PM_APIVERSION "5.005"
 
+/* 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 2
+
 /* I_LIBUTIL:
  *     This symbol, if defined, indicates that <libutil.h> exists and
  *     should be included.
index e66e0c5..209c96f 100644 (file)
@@ -3156,6 +3156,13 @@ sed <<!GROK!THIS! >$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 <libutil.h> exists and
  *     should be included.
index 9afa44d..45b2f8e 100644 (file)
@@ -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
index a56b4a8..24dcea2 100644 (file)
@@ -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 (file)
--- 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);
 }
-
index 8bb7536..e96c683 100755 (executable)
@@ -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<