[Top][All Lists]

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


From: Léa Gris
Date: Thu, 19 Aug 2021 18:18:46 +0200
User-agent: Telnet/1.0 [tlh] (PDP11/DEC)

Le 19/08/2021 à 16:41, Eli Schwartz écrivait :
On 8/19/21 9:41 AM, Léa Gris wrote:

The error occurs, one would imagine, during the "convert string to
float" stage, after parsing argv or forking to bc or whatever, but
*before* passing it as an argument to printf(3). Here, bash is just
doing good error checking -- if you used
strtof("3.14159265358979323844", NULL) under a fr_FR.UTF-8 locale, it
would silently drop everything after the ".", and you would
"successfully" print 3,0000, but bash reports an error message.

A programming language shall distinguish between display format and data format.

Locale settings are for display format and shall not interfere with arguments parsing which is data format, or it create such data portability issues.

This is exactly how I read the note from the POSIX documentation:


  The bc utility always uses the <period> ( '.' ) character to represent
  a radix point, regardless of any decimal-point character specified as
  part of the current locale. In languages like C or awk, the <period>
  character is used in program source, so it can be portable and
  unambiguous, while the locale-specific character is used in input and
  output. Because there is no distinction between source and input in
  bc, this arrangement would not be possible. Using the locale-specific
  character in bc's input would introduce ambiguities into the language


In languages like C or awk, the <period> character is used in program source, 
so it can be portable and unambiguous

printf arguments are program source even if argument comes from a variable.

All things considered, if you are using floating-point numbers in a shell script, you are clearly not using the right tool for the job, but sometimes options are limited or not under your control.

Having a feature implemented in such a way, *that it cannot be used reliably or requires heavy work-around* (especially if you both need to process floating-point data in a portable format, and display in locale format)… is just calling for frustration and sorry errors:

For the record:

ash -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
Pi: 3.1416

bash -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
bash: line 1: printf: 3.14159265358979323844: invalid number
Pi: 3,0000

dash -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
Pi: 3.1416

ksh -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
Pi: ksh: printf: 3.14159265358979323844: arithmetic syntax error
ksh: printf: 3.14159265358979323844: arithmetic syntax error
ksh: printf: warning: invalid argument of type f

mksh -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
Pi: 3,1416

zsh -c 'LC_ALL=fr_FR.utf8; printf "Pi: %2.4f\\n" "$(echo "4*a(1)" | bc -l)"'
Pi: 3,1416

Léa Gris

reply via email to

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