Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to format a floating point for display based on locale environment variables?

Lets say I have several floating point numbers to print in a Bash script. But I want the floating points numbers displayed accordingly to the LC_NUMERIC locale environment variable.

#!/usr/bin/env bash

# For consistent/reproducible error messages in this sample code
LANGUAGE=C

# The speed of light in vacum in m.s
declare -r const_C=299792458

# Declare separately when assigning command output
declare -- const_pi

# π is 4 × arc-tangent of 1, using bc calculator with math library
typeset -r const_pi="$(bc --mathlib <<<'scale=20; 4*a(1)')"

# Do it in US's English
LC_NUMERIC=en_US.utf8
printf 'LC_NUMERIC=%s\n' "${LC_NUMERIC}"
printf 'Speed of light in vacuum is:\nC=%.f m/s\n\nπ=%.10f\n' \
  "${const_C}" \
  "${const_pi}"

echo $'\n'

# Do it in France's French
# it fails because floating point format
# changes for printf parameters
LC_NUMERIC=fr_FR.utf8
printf 'LC_NUMERIC=%s\n' "${LC_NUMERIC}"
printf 'La vitesse de la lumière dans le vide est :\nC=%.f m/s\n\nπ≈%.10f\n' \
  "${const_C}" \
  "${const_pi}"

Actual output:

LC_NUMERIC=en_US.utf8
Speed of light in vacuum is:
C=299792458 m/s

π=3.1415926536


LC_NUMERIC=fr_FR.utf8
La vitesse de la lumière dans le vide est :
C=299792458 m/s

a.sh: line 29: printf: 3.14159265358979323844: invalid number
π≈3,0000000000

This is a perfectly expected result because printf %f format expects the argument be formatted according to LC_NUMERIC.

Then how do you display arbitrary floating-point numbers that are stored in POSIX or bc's format but having display reflect the settings of LC_NUMERIC?

What if I want the French part of the code, with the following output?

Expected output for French:

La vitesse de la lumière dans le vide est :
C=299792458 m/s

π≈3,1415926536
like image 969
Léa Gris Avatar asked Jul 05 '19 21:07

Léa Gris


People also ask

What is locale environment variable?

LC_ALL is an environment variable that overrides all of these. It is typically used in scripts that run particular programs. For example, configure scripts generated by GNU autoconf use LC_ALL to make sure that the configuration tests don't operate in locale dependent ways.

How do I know where my environment variable is set?

Select Start > All Programs > Accessories > Command Prompt. 2. In the command window that opens, enter echo %VARIABLE%. Replace VARIABLE with the name of the environment variable you set earlier.

What is the format specifier for floating point numbers?

Every format specifier begins with the percentage ( %) symbol; a type character follows it. The format specifier for floating-point numbers deals with a number’s fractional and integral parts. We can format the values of double, Double, float, Float, and BigDecimal data types using floating-point number format specifiers.

Can all real numbers be represented in floating point format?

Not all real numbers can exactly be represented in floating point format. For any numberwhich is not floating point number, there are two options for floating point approximation, say, the closest floating point number less than x as x_ and the closest floating point number greater than x as x+.

How do you format a float value?

To format the float value up to two decimal places, use the % .2f. x = 211911461911461819112146 y = 2**70 z = x / y print ( "%.2f" % z) To format up to three decimal places, use the %.3f. x = 211911461911461819112146 y = 2**70 z = x / y print ( "%.3f" % z)

What is the difference between range and accuracy in floating point representation?

Accuracy in floating point representation is governed by number of significant bits, whereas range is limited by exponent. Not all real numbers can exactly be represented in floating point format.


1 Answers

This is a problem with Bash's own built in printf command. The standalone printf works OK.

LC_NUMERIC=fr_FR.UTF8     printf 'Bad  : %f\n' 3.14
env LC_NUMERIC=fr_FR.UTF8 printf 'Good : %f\n' 3.14

Output

script.sh: line 4: printf: 3.14: invalid number
Bad  : 0,000000
Good : 3,140000
like image 168
n. 1.8e9-where's-my-share m. Avatar answered Oct 22 '22 14:10

n. 1.8e9-where's-my-share m.