scriptz
scriptz

Reputation: 515

cannot get complex calculation to work in bc

I use qalculate as my day-to-day calculator and it's great! It is easy enough to type in something like:

(1+10^(-17.2/20)) / (1-10^(-17.2/20))

and get the right answer:

1.320289

But trying to get bc to do this sort of calculation in a bash script is frustrating. Google search spits back many pages demonstrating the simplest kinds of simple math examples using bc, but I have yet to find any pages tackling how to perform more complex calculations. When I type the following at CL:

echo 'scale=50; (1+10^(-17.2/20)) / (1-10^(-17.2/20))' | bc -l

I get the following warning-errors:

Runtime warning (func=(main), adr=25): non-zero scale in exponent
Runtime warning (func=(main), adr=44): non-zero scale in exponent
Runtime error (func=(main), adr=46): Divide by zero

If I try something similar but a little simpler like:

echo '(1-10^(-17.2/20))' | bc -l

I do get an answer, buts it's wrong and comes complete with a warning.

Runtime warning (func=(main), adr=18): non-zero scale in exponent
0

What could bc be having trouble with here, or rather what am I not doing correctly to get bc to perform these calculations properly?

Upvotes: 0

Views: 1267

Answers (2)

genisage
genisage

Reputation: 1169

from the bc man page:

expr ^ expr: The result of the expression is the value of the first raised to the second. The second expression must be an integer.

but since if x = a^b, then ln(x) = ln(a^b) = b(ln(a)), we can see that x = exp(b(ln(a))), so if you want to raise things to fractional b's you can use that.

Note: In bc the actual exp and ln functions are e and l.

Upvotes: 3

Tom Fenech
Tom Fenech

Reputation: 74605

Unfortunately, bc doesn't support exponents such as -17.2/20. If you don't require 50 decimal places of precision, one option would be to use another tool such as awk:

$ awk 'BEGIN{print (1+10^(-17.2/20)) / (1-10^(-17.2/20))}'
1.32029

You can pass variables to awk from your script like this:

$ awk -va="-17.2" -vb="20" 'BEGIN{print (1+10^(a/b)) / (1-10^(a/b))}'
1.32029

Upvotes: 3

Related Questions