Bash For-loops with Floats

I am trying to make a for loop which goes from 0.01 to 0.10

According to [1], bash does not support floating-point arithmetic, and one needs to use an external utility like bc.

I tried the following:

initial=0.01
end=0.1
inc=0.01
for ((test="$initial" | bc; test<"$end" | bc; test+="$inc" | bc))
do
    echo "done with: $test" | bc 
done

I get an error saying:

((: test=0.01 | bc: syntax error: invalid arithmetic operator (error token is ".01 | bc")

Any ideas about how this could be implemented?

[1] "Invalid Arithmetic Operator" doing floating-point math in bash

Upvotes: 0

Views: 901

Answers (4)

bobsacameno
bobsacameno

Reputation: 765

Another way to do this is to use seq.

The following script

#!/bin/usr/env bash

initial=0.01
end=0.1
inc=0.01

for i in $(seq $initial $inc $end)
do
   echo $i
done

gives the output:

0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.1

Upvotes: 1

L&#233;a Gris
L&#233;a Gris

Reputation: 19545

Another way using bc for comparison and computations, that may be needed with other loop conditions:

#!/usr/bin/env bash

# set numeric format to POSIX to avoid
# floating point representation discrepancies
# between bc and printf '%f'
LC_NUMERIC=POSIX

initial=0.01
end=0.1
inc=0.01

cur=${initial}
while [[ $(bc <<<"${cur} < ${end}") -eq 1 ]]; do
  printf '%f\n' "${cur}"
  cur="$(bc <<<"${cur} + ${inc}")"
done

Upvotes: 3

Michael Jaros
Michael Jaros

Reputation: 4681

You do not need floating-point arithmetics to loop from 0.01 to 0.10. Instead, you can use the fact, that in your case, you are basically iterating from 1 to 10, zero-padding that number to 2 places and prefixing it with 0.:

for i in {1..10}
do 
  printf "0.%02s\n" "$i"
done

Note that this approach requires you to match the field width given to printf to the number of decimal places you want to use, e.g. if you want to go from 0.001 to 0.1, you would have to write {1..100} and printf "0.%03s\n".

Upvotes: 2

Cyrus
Cyrus

Reputation: 88583

for i in $(LC_ALL=en_US.UTF-8 seq $initial $inc $end); do echo $i; done

Output:

0.01
0.02
0.03
0.04
0.05
0.06
0.07
0.08
0.09
0.10

Upvotes: 3

Related Questions