1

When I type in the following commands:

result=$(( ($1-32)*(5/9) ))
echo $result

the variable, result, always evaluates to an integer, whether the equation evaluates to a decimal number or not. Why is this?

Eliah Kagan
  • 116,445
  • 54
  • 318
  • 493
  • 1
    Related: [Why does division in bash arithmetic compute most percentages as 0?](https://askubuntu.com/questions/825574/why-does-division-in-bash-arithmetic-compute-most-percentages-as-0) (But that problem can be solved by reordering the operations, which wouldn't really work here because numbers like 1.65 would round to 1.) – Eliah Kagan Sep 09 '19 at 19:23
  • 1
    Possible duplicate of [Why let command doesn't work to add real numbers?](https://askubuntu.com/questions/440654/why-let-command-doesnt-work-to-add-real-numbers) – WinEunuuchs2Unix Sep 09 '19 at 19:39
  • @WinEunuuchs2Unix I don't think OP is using `let`, hence, it's not a dupe. – Kulfy Sep 10 '19 at 05:54
  • @Kulfy True but both questions are about about fractions / floating point math not supported in bash. Also consider `let` and `$((` can be used interchangeably sometimes. – WinEunuuchs2Unix Sep 10 '19 at 11:01
  • @WinEunuuchs2Unix Agreed. But as per [Ravexina's answer](https://askubuntu.com/a/939302/816190), one does **expansion** while other does **evaluation**. Thin line of difference among them. But still I'm not convinced that it's a dupe. – Kulfy Sep 10 '19 at 12:18

1 Answers1

9

The bash shell natively only supports integer arithmetic. In particular, since 5 is less than 9, (5/9) will evaluate to zero regardless of the other terms in your product.

Depending on your requirements, you might be able to do what you want (still using integer arithmetic) by changing the order of operations i.e. whereas

$ bash -c 'echo $(( ($1-32)*(5/9) ))' bash 35
0

if you allow * and / to have their natural precedence

$ bash -c 'echo $(( ($1-32)*5/9 ))' bash 35
1

because (35-32)*5 is 15, which when integer-divided by 9 yields 1. If you actually want floating point arithmetic then you can use an external program such as bc or awk e.g.

$ bash -c 'echo "scale = 2; ($1-32)*(5/9)" | bc' bash 35
1.65

or switch to a shell that supports floating point arithmetic, such as ksh:

$ ksh -c 'echo $(( ($1-32)*5/9 ))' ksh 35.0
1.66666666666666667

(note the use of argument 35.0 to force floating point promotion).

steeldriver
  • 131,985
  • 21
  • 239
  • 326
  • `var=35; <<<"scale = 3; ($var-32)*5/9" bc` maybe helps explaining. It corresponds to the command line `var=35; echo "scale = 3; ($var-32)*5/9" | bc` – sudodus Sep 09 '19 at 17:28