[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Incorrect output with OFMT="%.15e"
From: |
Andrew J. Schorr |
Subject: |
Re: Incorrect output with OFMT="%.15e" |
Date: |
Sun, 7 May 2023 21:34:28 -0400 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
Hi,
On Sun, May 07, 2023 at 04:50:40PM -0700, Keith Thompson wrote:
> BEGIN {
> x = 9
> y = 9.001
> z = 9e50
>
> printf("Using printf: %.15e\n", x)
> printf(" %.15e\n", y)
> printf(" %.15e\n", z)
>
> OFMT="%.15e"
> printf("Using OFMT: "); print(x)
> printf(" "); print(y)
> printf(" "); print(z)
> }
>
> on Ubuntu using versions of awk from 3.1.8 to 5.2.1. The output was
> consistently:
> ```
> Using printf: 9.000000000000000e+00
> 9.000999999999999e+00
> 9.000000000000000e+50
> Using OFMT: 9
> 9.000999999999999e+00
> 900000000000000027129553701548362001410714104758272
> ```
>
> The output should be in scientific notation for all values.
> Note that the behavior differs for different values.
> (/usr/bin/original-awk and mawk have a similar bug, but the
> output is slightly different.)
>
> Using printf rather than setting OAWK is a straightforward
> workaround.
Thanks for the report. I think what you're running into here is
that before using OFMT, gawk tries to ascertain whether the numeric
value is actually an integer. If it believes it to be an integral
value, then it prints it as an integer instead of using OFMT.
Or at least that's how I read the code.
In the Posix AWK spec, this portion seems relevant:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html
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. Any other numeric value shall be converted
to a string by the equivalent of a call to the sprintf function with the
value of the variable CONVFMT as the fmt argument and the numeric value
being converted as the first and only expr argument. The result of the
conversion is unspecified if the value of CONVFMT is not a floating-point
format specification. This volume of POSIX.1-2017 specifies no explicit
conversions between numbers and strings. An application can force an
expression to be treated as a number by adding zero to it, or can force it
to be treated as a string by concatenating the null string ( "" ) to it.
I believe the same logic is used for OFMT conversions as for CONVFMT.
Regards,
Andy