On 4/11/22 11:52, Chet Ramey wrote:
On 4/9/22 3:31 PM, Paul Eggert wrote:
It sounds like there are three cases.
1. If the `L' modifier is supplied, as an extension (POSIX doesn't allow
length modifiers for the printf utility), use long double. This would
work in both default and posix modes.
2. In posix mode, use strtod() and double.
3. In default mode, use the existing code to get the highest possible
precision, as the code has done for over 20 years.
That'll fix the POSIX compatibility bug. However, it may be better for
Bash to just do (1) if 'L' is supplied and (2) otherwise, even if this
is less precise than (3). Doing it this simpler way will likely be more
useful for the small number of people who care whether 'printf' uses
'double' or 'long double' internally (and nobody else will care).
Doing it this way is what BSD sh does, and it's good to be compatible
with BSD sh. Similarly for dash and for other shells.
It's also what other GNU programs do. For example, on x86-64:
$ awk 'BEGIN {printf "%.100g\n", 0.1}'
0.1000000000000000055511151231257827021181583404541015625
$ emacs -batch -eval '(message "%.100g" 0.1)'
0.1000000000000000055511151231257827021181583404541015625
$ printf "%.100g\n" 0.1
0.1000000000000000000013552527156068805425093160010874271392822265625
printf is the outlier here, and although its answer is closer to the
mathematical value, that's not as useful as being closer to what most
other apps do.
Perhaps it was OK for sh printf to use long double 20 years ago. I even
had a hand in implementing that.[1] But nowadays it feels like a
misfire. The overwhelming majority of apps that have developed over the
past 20 years that use newer languages like JavaScript and Java, do not
support 'long double'; when interoperating with these apps, using 'long
double' in Bash printf likely causes more trouble than it cures.
[1]:
https://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=830de2708207b7e48464e4778b55e582bac49832