How to format decimal number to display the preciding zero but not the trailing ones?
Solution 1
Floating point arithmetic support in bash is very poor. You can still use printf
, though:
printf '%5.3f\n' $f
printf '%.3g\n' $f
If you just want to prepend 0 to ., you can use parameter expansion:
f=${f/#./0.}
# if negative numbers are possible, too
f=${f/#-./-0.}
Solution 2
In bc
, scale
is a special variable that is used to limit the scale (the number of digits after the comma) of the result of some operators like /
(division). It is not the precision in numbers displayed by bc
, it's used in computation.
For instance, in scale=1; 1/3
, the result is 0.3
(3/10
), which is quite far from 1/3
.
You should use large scale values for your computation, and only reduce scale
for display (by instance, by dividing by 1
in the end).
Compare:
$ echo "scale=100; r=1/3*300; scale=3; r/1" | bc
99.999
with:
$ echo "scale=3; 1/3*300" | bc
99.900
I'd write it:
n=10
echo "
s = 0.030
f = 0.150
n = $n
r = 20
scale = 100
d = (f - s) / n
scale = 3
for (i = s; i <= f; i += d) i/1" |
bc |
sed 's/^\./0./;s/0*$//' |
while read f; do
h5totxt "hsli$f.h5" | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200
done
Related videos on Youtube
mareicha
Updated on September 18, 2022Comments
-
mareicha over 1 year
I have the following script on Ubuntu 14.04.1 LTS 64-bit bash command prompt:
S=0.030 F=0.150 N=10 reso=20 DIFF=`echo "scale=3; $F - $S" | bc -l` df=`echo "scale=3; $DIFF / $N" | bc -l` is=`echo "scale=3; $S / $df" | bc -l` if=`echo "scale=3; $F / $df" | bc -l` cd wgdisp-out for i in `seq 0 $N` do f=`echo "scale=3; $S + $i * $df" | bc -l | awk ' sub("\\.*0+$","") '` #h5totxt hsli0$f.h5 | harminv -vt 0.1 -w 2-3 -a 0.9 -f 200 | sed -n '/^[[:digit:]]/p' | cut -d , -f 1 echo $f done
I would like to have f displayed as
0.03, 0.042, 0.054, .... 0.138, 0.15
and this is critical since f is used inside file names such ashsli0.03.h5
. Can someone point me in the right direction? I am not pretty familiar with arithmetic in shell.EDIT: I tried the following construct, but it does not yield the desired output; furthermore the scale option for
bc
does not seem to work.f=`echo "scale=3; $S + $i * $df" | bc | sed -e 's/^\./0./' -e 's/$^\/0/./'`
EDIT2: Got it working with the following single command:
f=`echo "scale=3; $S + $i * $df" | bc | sed -e 's/^\./0./;s/[0]*$//g'`
-
Admin about 9 yearsUse
awk
instead ofbc
. -
Admin about 9 years@StéphaneChazelas Unfortunately, I am not that experienced with
regular expression
andawk
I think I will try the printf solution.
-
-
mareicha over 9 yearsWell I somehow managed to have the leading zero printed but now I would like to get rid of the trailing zeros is it possible with this construct?
-
choroba over 9 years@Vesnog: Do you really need it? I'd like the fixed-length filenames more.
-
choroba about 9 years@Vesnog: Check the update.
-
mareicha about 9 years@choraba Okay thanks, I think I should get my hands on regexs ASAP.
-
choroba about 9 years@Vesnog: There's no regex. It just replaces
.
at the beginning with0.
. -
mareicha about 9 years@StéphaneChazelas Can I use
sed
to achieve that effect? Like f=echo "scale=3; $S + $i * $df" | bc | sed -e 's/^\./0./;s/$^\/0/./'
-
choroba about 9 years@Vesnog: Parameter substitution would be faster than sed. Also, the second substitution makes no sense (there can't be anything after the end of line).
-
mareicha about 9 years@choroba As I have said I am not familiar with regexs how can I have
sed
check if there is a trailing zero to remove it.