0

I am attempting to use a for loop to run command line arguments, I have never attempted this and I am having some trouble.

I am using the following commands:

for((a=1; a<20; a++)); 
do 
    ./a.out -N 10000 -D .25*a -E 0.7788007831;
done

I am using the getopt function in c to read in values. I want to try different values of D (called Delta in the output). However when I run this command I get:

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704 
Error is :          0.020097
Delta used:         0.250000

...

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

I'm not sure what the problem is though.

ilkkachu
  • 138,973
  • how is the shell supposed to know how to multiply that .25*a versus turning it into a glob or ... ? – thrig Jan 02 '18 at 15:54

1 Answers1

2

For one, if you want to refer to a shell variable, you need to use the $foo notation. a is just the letter "a" (in the same way 10000 is just the five digits), but $a expands to whatever the variable contains at the time.

Two, to do arithmetic in the shell, the syntax for arithmetic expansion is $(( expression )), so you could write $(( 25 * $a )) to get the value of a times 25. (as a base 10 number.)

Though the problem you would face here, is that Bash (and the POSIX shell) can only do arithmetic on integers, so multiplying with 0.25 isn't going to work.

In zsh, the floating point arithmetic works, so you could do e.g.

for ((a=1; a<20; a++)); do 
    echo $((.25 * $a))
done

But in Bash or standard shell, you'll need to use an external program to do the maths:

for ((a=1; a<20; a++)); do 
    echo $( echo ".25 * $a" | bc -l )
done

Or in your command:

for ((a=1; a<20; a++)); do 
    ./a.out -N 10000 -D $( echo ".25 * $a" | bc -l ) -E 0.7788007831;
done

Of course, if the program you're running can do the multiplication and you just want to pass the strings .25*1, .25*2 etc to it, then you'd use

... -D ".25*$a"

with the quotes around it, since otherwise the * is taken as a filename match (glob). (Actually you'll usually want to put quotes around most places where you use variable expansions or command substitutions, but let's just refer to When is double-quoting necessary? on that.)

There's a number of ways for doing floating point math in the shell presented here: How to do integer & float calculations, in bash or other languages/frameworks?

ilkkachu
  • 138,973