Date: Fri, 17 Sep 2010 21:43:34 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: "David O'Brien" <obrien@FreeBSD.org> Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Jilles Tjoelker <jilles@stack.nl> Subject: Re: svn commit: r212374 - head/usr.bin/printf Message-ID: <20100917212708.Y771@delplex.bde.org> In-Reply-To: <20100917002101.GA13653@dragon.NUXI.org> References: <201009091927.o89JReXm022426@svn.freebsd.org> <20100909195302.GA48144@stack.nl> <20100917002101.GA13653@dragon.NUXI.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100917212708.Y771>