Can expr deal with decimals?

Hello,
Im trying to work on a small script for a formula converting temperatures, Celsius to fahrenheit.

I have a formula, and it works.... it works every way I try it. But it keeps giving me the wrong results every time with expr.

The formula for C to F would be:
divide by 5, multiply by 9, add 32.

So..... simple code here

read c
f= `expr $c / 5 \* 9 + 32`
echo $f

The problem is, its never correct because expr can't seem to add the decimals right.

For instance 32 degrees celcius.
f=`expr 32 / 5 \* 9 + 32` gives me 86 for some reason. It should give 89 (or 89.6)

I have also tried it another way, which seems odd, but still should give correct results.

f=`expr 9 / 5 \* $c + 32`

Again, I have tested, it should be 89, but it ends up giving me 64.

Because expr 9 / 5 is giving me 1, instead of 1.8
So 1 * 32 = 32 + 32 = 64.
It should be 1.8 * 32 = 57.6 + 32 = 89.6

It seems like my problem is the fact that expr won't account for decimals.
Is there a way to get it to acknowledge the decimals?
Or is this not possible with the expr command?

Thanks a lot

I think expr does not work with floating point number. Try awk instead:-

echo | awk ' { printf "%0.2f\n", (57.6 + 32); } '

Or use bc

echo "scale=2; 57.6 + 32" | bc

expr does not "do" floating point numbers (decimal numbers).

bc -l

does.

 echo "1.356 * 1.2" | bc -l

The awk command does double precision (15 digits of floating point) as well.

echo "13 14.112" | awk '{print $1 * $2}'

Thanks a lot,

Im having some trouble with bc too.

echo $c / 5 \* 9 + 32 | bc
echo 32 / 5 \* 9 + 32 | bc

gives me 86 (instead of 89)

Im not sure how it is rounding 89.6 to 86..... its making no sense to me :confused:

adding the -l

echo 32 / 5 \* 9 + 32 | bc -l

gives me 89.600000000000000000
Which is correct. But for the output file, I just need the whole number. (89)

You have to use scale to get accurate results. Here is what is happening:-

See the difference in results with scale and without scale:-

echo '( 32 / 5 )' | bc
6
echo '( 32 / 5 ) * 9 ' | bc
54
echo 'scale=2; ( 32 / 5 )' | bc
6.40
echo 'scale=2; ( 32 / 5 ) * 9' | bc
57.60

I hope you understood how 89.6 got rounded to 86 :slight_smile:

1 Like

That explains it......
Now I see why it rounded it like that......

but even if I do a scale=1, I get 89.6
scale=0 obviously gives me the rounded "86"

So is there not a way to just get 89?

 
$ res=$(echo 32 / 5 \* 9 + 32 | bc -l); 
$ echo ${res%%.*}
89
1 Like

A simple way might be to use bc -l and use printf to print the required precision:

$ c=32
$ f=$(echo "$c / 5 * 9 + 32" | bc -l)
$ printf "%.1f\n" "$f"
89.6
$ printf "%.0f\n" "$f"
90

If you run the following commands with a Korn shell newer than the November 16, 1988 version, the following will work:

echo $(($c / 5. * 9 +32))

or if you want it rounded (rather than truncated) to a whole number:

printf "%.0f\n" $(($c / 5. * 9 + 32))

Thanks a lot everyone. I got that part all sorted out now.
Everything is done, I wrote the whole shell script and it was working fine.

I have temperatures from another file to use as an input file.
ex.... of input file
0
5
10
32
64

I also have the conversion formula in a separate file (f2c.ss)

I needed to have my shell script take those and convert them from Celsius to Fahrenheit, and put them in an output file.

The problem is, I had everything done, and it worked. But I was using a while loop, and I just found out that I need to use as for/do loop.

This is what im working with right now,

This is a snippet of the for loop in my main script file:

for temp in `cat $input_file`
do
./c2f.ss "$temp"
echo $temp
done

And this is my c2f.ss file (which tested by itself, works perfect)

read c
f=$(echo $c / 5 \* 9 + 32 | bc -l);
echo $c "=" ${f%%.*} >> ans.file

The c2f script works great now, thanks to the help of all of you.
But something is wrong with my for loop, and I can't figure it out.

when I run my main script I keep getting the following error:

main: 39: ./c2f.ss: Permission denied
0
main: 39: ./c2f.ss: Permission denied
5
main: 39: ./c2f.ss: Permission denied
10
main: 39: ./c2f.ss: Permission denied
32
main: 39: ./c2f.ss: Permission denied
64

I had it all done with a while loop. But I was told that I have to use a for loop, and was given the code for the for loop. But there is obviously an error in the for loop code.

Anyone have any ideas?

Use a while loop instead in your main script:-

while read value
do
    ./c2f.ss $value
    echo $value
done < $input_file 

Accept the argument passed in your c2f.ss script & do the math:-

c=$1
f=$(echo $c / 5 \* 9 + 32 | bc -l);
echo $c "=" ${f%%.*} >> ans.file

Also make sure your script c2f.ss is executable:-

chmod +x c2f.ss

Thanks,

I was using a while loop, But I was told I had to use a for loop.....:frowning:

That is a Useless Use of Backticks hence I suggested to use while loop instead which is the right way to do.

1 Like