bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gawk number to string bug


From: Paul Eggert
Subject: Re: gawk number to string bug
Date: Sun, 25 Dec 2005 01:38:17 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Eli Zaretskii <address@hidden> writes:

> I think we need to consult Posix, but I don't have a copy handy, and
> all the on-line versions I've known about were removed by
> organizations that want $$.

POSIX 1003.1-2004 is available at no cost at www.opengroup.org.
<http://www.opengroup.org/onlinepubs/000095399/utilities/awk.html> says:

  A numeric value that is exactly equal to the value of an integer
  (see Concepts Derived from the ISO C Standard) shall be converted to
  a string by the equivalent of a call to the sprintf function (see
  String Functions) with the string "%d" as the fmt argument and the
  numeric value being converted as the first and only expr argument.

The "Concepts Derived from the ISO C Standard" say that the integers
being referred fit in signed long.  The width of signed long is not
specified, other than it has to be at least 32 bits, so it is clearly
OK for gawk to use intmax_t instead, or even to use uintmax_t for
values that are known to be nonnegative.


The rounding patch that Andrew J. Schorr submitted in
<http://lists.gnu.org/archive/html/bug-gnu-utils/2005-12/msg00098.html>
doesn't suffice in general, because it relies on undefined behavior.
As one example, on Solaris 8 sparc 64-bit (gcc -m64), it prints
incorrect answers for David Ellsworth's test case
<http://lists.gnu.org/archive/html/bug-gnu-utils/2005-12/msg00092.html>.
With Andrew's patch, gawk prints these lines:

2^63= 9223372036854775807 9223372036854775808 9.22337e+18
2^64= 1.84467e+19 18446744073709551615 1.84467e+19

The "9223372036854775807" is incorrect, since 2**63 is not
equal to 9223372036854775807.  Furthermore, the "18446744073709551615"
is incorrect, since 2**64 is not equal to 18446744073709551615.
Andrew found another case where his patch prints an off-by-one number in
<http://lists.gnu.org/archive/html/bug-gnu-utils/2005-12/msg00099.html>.


The rounding patch that I submitted in
<http://lists.gnu.org/archive/html/bug-gnu-utils/2005-12/msg00097.html>
handles this correctly on 64-bit hosts, by pre-rounding the integers
in question before using them to compare against doubles.  For the
above-mentioned test case, my patch prints the following, which is valid:

2^63= 9.22337e+18 9223372036854775808 9.22337e+18
2^64= 1.84467e+19 1.84467e+19 1.84467e+19

My patch doesn't address the buffer overflow issue, though.


Also, now that I've seen the followup, I agree that simulating %d with
%.0f is not a good idea in general.  It can work in some special cases
(and it would be allowed, in those cases), but they'd have to be
checked carefully.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]