On Thu, 16 Sep 2010, David O'Brien wrote:

...
Interestingly, we may not be compliant with susv3 if I am reading this
correctly:

   The printf utility is required to notify the user when conversion
   errors are detected while producing numeric output; thus, the
   following results would be expected on an implementation with 32-bit
   twos-complement integers when %d is specified as the format operand:

   Argument      Standard Output   Diagnostic Output
   5a            5                 printf: "5a" not completely converted
   9999999999    2147483647        printf: "9999999999" arithmetic overflow
   -9999999999   -2147483648       printf: "-9999999999" arithmetic overflow
   ABC           0                 printf: "ABC" expected numeric value


 $ uname -m
 i386
 $ for A in 5a 9999999999 -9999999999 ABC do /usr/bin/printf "%d\n" $A ; done
 printf: 5a: not completely converted
 5
 9999999999
 -9999999999
 printf: ABC: expected numeric value
 0

Though this is in the "informative" section, so maybe this is just one
set of compliant output.  Though It is my read that printf(1) should
behave like printf(3), which the above does not for these long long int
values.

The implementation actually uses [u]quad_t integers (blech -- it should use
[u]intmax_t integers).  This may be conformant.  POSIX has the general
bug of making low-quality implementations, that only support plain integers
for command-line options, conformant, and may even require not supporting
larger integers in some cases, but hopefully it doesn't require this
bug for printf(1).

   #include <stdio.h>
   int
   main(void)
   {
           printf("%d\n", 9999999999);
           printf("%d\n", -9999999999);
           return 0;
   }

Restricting to plain int for printf(1) would be less than useful, since
unlike printf(3), it has no way of controlling the integer size -- even
"%ld" format is "illegal" (should be "invalid") for printf(1).  Users
wanting to handle large integers would have to use floating point with
"%.0f" format, which has some advantages anyway, but printf(1)'s FP
format is only double precision, so it doesn't work right for integers
= 2**53 even on arches that have working long double precision.
Rounding errors are also not reported for integers >= 2**53 when
represented as doubles:

$ printf %.0f\\n 9999999999999999
10000000000000000

and its documentation is slightly wrong in saying (re-quoting the above):

   The printf utility is required to notify the user when conversion
   errors are detected while producing numeric output; thus ...

since in the floating point case, it is very unusual for there not to be
a rounding error (e.g., 0.1 is not exactly representable in base 2 FP),
so reporting _all_ rounding errors would be wrong.  In fact, it doesn't
seem to be done at all for rounding errors.

Bruce
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to