0

I've tried many different ways of evaluating the mess below as a float. I think I'm almost there with the use of bc but it's still not evaluating.

s=$((($s+((${flowx[$(($a+1))]}-(${flowx[$a]}))*(${flowy[$(($a+1))]}+${flowy[$a]}))/2) | bc))

Any input?

7
  • 2
    BashFAQ #22 is your friend -- mywiki.wooledge.org/BashFAQ/022 -- but it tells you to only use bc, which... well, yeah. Use bc, don't use $(( )). Since you already know that bc exists, and that it can do floating-point math, how is this a question? Commented Sep 4, 2014 at 20:01
  • Can you provide an example of numbers you're running through that thing? What are you trying to achieve anyway? Commented Sep 4, 2014 at 20:01
  • Hsve you considered using awk/perl/python/ruby? Commented Sep 4, 2014 at 20:03
  • @dawg, pah; dc gives you true arbitrary-precision math rather than the compromises inherent in IEEE floating-point. It's actually more accurate (if asked to be) than what awk/perl/python/ruby/etc. do out-of-the-box with floats. Commented Sep 4, 2014 at 20:21
  • Of course you are correct. Just seems a lot of work to get there ;-) Commented Sep 4, 2014 at 20:22

3 Answers 3

3

Don't use $(( )) at all.

For instance, taking a relevant part of your calculation:

s=$(bc <<<"$s + ( ( ${flowx[a+1]} - ${flowx[a]} ) * ( ${flowy[a+1]} + ${flowy[a]} ) ) / 2")

As long as flowx and flowy are standard integer-indexed arrays rather than associative arrays, you don't even need to use $(( )) when indexing into them (or $ operators inside those indices), as the index of a nonassociative array in bash is a math context by default.

Or, more readably than all these nested parens, use dc (here, configured with 10 digits of precision):

s=$(dc <<EOF
10 k
${flowx[a+1]}
${flowx[a]}
-
${flowy[a+1]}
${flowy[a]}
+
*
$s +
2 /
p
EOF
)

See? Much more readable.

Sign up to request clarification or add additional context in comments.

6 Comments

My arrays are standard integer-indexed. Using what you wrote, it gave me this error: (standard_in) 1: syntax error Do you know what that could be from?
First, <<< is a bashism -- if you're using /bin/sh rather than bash, there's potential for an error there. Beyond that, change the bc <<< to an echo and hand-check the expansion -- this is off-the-cuff rather than something that could be tested, since you didn't provide samples of your arrays' values &c. sufficient to allow testing of any proposed solution.
@CharlesDuffy change the flowax to flowx in the bc line... ;)
I updated the echo and the flowx (I feel so retarded about that one...) and now it's giving me this error: File echo0 + ( ( -0.0231005 - -0.0217739 ) * ( 0.0478359 + 0.0478459 ) ) / 2 is unavailable. Those numbers are the kinds of numbers that I'm dealing with
@JoshuaJenkins, did you write <<<, exactly as given? If you wrote, say, <"..." rather than <<<"...", that would do what you described. (Even if that guess is incorrect, it'd be helpful if you provided a copy-and-paste of the invocation).
|
1

You can avoid all quotes and such things if you instead of the hereline (as @CharlesDuffy in the otherwise great answer recommends) will use the heredoc as like:

flowx=(0.124852 -0.0156593 -0.0932662 -0.0464323 0.0305706 0.00833429 0.0245359 0.0292034 -0.0564935)
flowy=(0.197532 0.120311 0.0864692 -0.0071995 0.097294 0.0624036 0.0825287 0 0.0340206)
a=1
s=0.1

res=$(bc -l <<EOF
$s + ( ( ${flowx[a+1]} - ${flowx[a]} ) * ( ${flowy[a+1]} + ${flowy[a]} ) ) / 2
EOF
)
echo "$res"

prints

.09197621484831000000

1 Comment

That worked! Thanks guys for all your help. I'm relatively new to all of this so my apologies for my lack of information. Thanks for your patience!
0

If ksh93 is installed on your system, I suggest you use it instead of bash for this task. It has built-in support for 64 bit IEEE floating point.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.