Jaguar
Jaguar

Reputation: 19

How to decrement floating point variables in a bash/batch script

I have written a program in C that requires four floating point variables to be passed to it as parameters. I would like to make a script that will run this program x times, with those four variables being decreased by a certain amount each time before the program is executed again.

Batch and bash don't support floating point numbers, but bc supports arbitrary precision which you can use in a bash script. I should say I haven't done any scripting before, except for a recent batch script which led me to realise batch wasn't suitable.

Being a relative noob in this area, my Googling and searching hasn't found anything particularly useful to me, so here I am.

Here is basically what I want:

MINX=-2.0
MAXX=0.8
MINY=-1.4
MAXY=1.4

for X times
{
    myprogram minX maxX minY maxY

    MINX-=0.1
    MAXX-=0.1
    MINY-=0.1
    MAXY-=0.1
}

So I want to run the program with the initial variables set, then decrement those variables and run the program again, and so on..

Everything I have found so far to do with floating point variables in bash + bc, I just can't seem to get to grips with it, so I'm hoping if I explain what I want to accomplish, one of you good people will be able to explain :)

Thanks in advance.

Upvotes: 2

Views: 672

Answers (3)

clt60
clt60

Reputation: 63902

bash & bc

#!/bin/bash
X=3     #cycle count

MINX=-2.0
MAXX=0.8
MINY=-1.4
MAXY=1.4

function fpcalc() {
    echo "scale=4; $@" | bc -l
}

X=$(($X + 1))
while let X-=1
do
    echo myprog  $MINX $MAXX $MINY $MAXY    #delete the echo
    MINX=$(fpcalc $MINX-0.1)
    MAXX=$(fpcalc $MAXX -0.1)
    MINY=$(fpcalc $MINY -0.1)
    MAXY=$(fpcalc $MAXY -0.1)
done

perl & bash

#delete the "echo" after the "xargs"
echo -2.0 0.8 -1.4 1.4 | perl -lane 'for(1..3){print"@F";@F=map{$_-=0.1}@F}' | xargs -L 1 echo myprog

In the both example is the count (X) = 3. Both produces output (when you remove the "echo" will run the myprog)

myprog -2.0 0.8 -1.4 1.4
myprog -2.1 0.7 -1.5 1.3
myprog -2.2 0.6 -1.6 1.2

Upvotes: 2

Dennis Williamson
Dennis Williamson

Reputation: 360035

Write the whole thing in AWK:

#!/usr/bin/awk -f
BEGIN {
    X = 100
    minX = -2.0
    maxX = 0.8
    minY = -1.4
    maxY = 1.4

    for (i = 1; i <= X; i++) {
        system("myprogram " minX " " maxX " " minY " " maxY)

        minX -= 0.1
        maxX -= 0.1
        minY -= 0.1
        maxY -= 0.1
    }
}

Upvotes: 4

ArjunShankar
ArjunShankar

Reputation: 23680

You can do this by writing an equivalent bc script (really, there is very little difference between your pseudocode, and bc syntax), call it myscript.bc or whatever else:

#!/usr/bin/bc -q

minx = -2.0
maxx = 0.8
miny = -1.4
maxy = 1.4

for (x = 0; x < 10; x = x+1)
  {
    print "myprogram ", minx, " ", maxx, " ", miny, " ", maxy, "\n"

    minx = minx - 0.1
    maxx = maxx - 0.1
    miny = miny - 0.1
    maxy = maxy - 0.1
  }

halt

Then simply pipe its output to (ba)sh:

bc -q myscript.bc | sh

Or, if the script is 'executable' (thanks to the shebang), you could even do:

./myscript.bc | sh

Upvotes: 1

Related Questions