svn commit: r212374 - head/usr.bin/printf
Bruce Evans
brde at optusnet.com.au
Fri Sep 17 11:43:39 UTC 2010
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
More information about the svn-src-head
mailing list