patternbashModerate
Calculating pi using bash
Viewed 0 times
calculatingusingbash
Problem
I've written a little program to calculate pi using the Nilakantha series:
For this formula, take three and start alternating between adding and subtracting fractions with numerators of 4 and denominators that are the product of three consecutive integers which increase with every new iteration. Each subsequent fraction begins its set of integers with the highest one used in the previous fraction. Carry this out even a few times and the results get fairly close to pi. (http://www.wikihow.com/Calculate-Pi)
I don't really understand other ways of calculating pi, or they take too long to perform.
I would really like to know how to detect when I get the same output multiple times, so I can tell the program to terminate when it has reached the most accurate version of pi possible.
Also if you have other suggestions on how to improve the code and/or know a better way of calculating pi (with some explanation), I would like to hear.
For this formula, take three and start alternating between adding and subtracting fractions with numerators of 4 and denominators that are the product of three consecutive integers which increase with every new iteration. Each subsequent fraction begins its set of integers with the highest one used in the previous fraction. Carry this out even a few times and the results get fairly close to pi. (http://www.wikihow.com/Calculate-Pi)
I don't really understand other ways of calculating pi, or they take too long to perform.
echo "Enter scale please"
read SCALE
VALUE=2
PI=3
FITNESS=1
while true
do
PI=$(echo "scale=$SCALE;$PI+(4/($VALUE*($VALUE+1)*($VALUE+2)))-(4/(($VALUE+2)*($VALUE+3)*($VALUE+4)))" | bc)
VALUE=$(($VALUE+4))
FITNESS=$(($FITNESS+1))
echo "###############"
echo "--> $FITNESS // $VALUE"
echo "$PI"
doneI would really like to know how to detect when I get the same output multiple times, so I can tell the program to terminate when it has reached the most accurate version of pi possible.
Also if you have other suggestions on how to improve the code and/or know a better way of calculating pi (with some explanation), I would like to hear.
Solution
I see a few things that could allow you to improve your program. First, though, I don't consider myself a bash expert, so there may well be better ways of doing these things.
Use a "shebang" line
As this question points out, you should always use a "shebang" line for your bash scripts. So the first line would be:
Pass values as arguments
Rather than prompting for the
Provide a stopping mechanism
As each term is calculated, eventually, it will be equal to zero given the passed
Indent
I don't know of a bash style guide (there probably is one!) but I like to see the contents of loops indented to make it easier to read.
Putting it all together
Here's a modification of your script with all of these suggestions implemented:
bashpi.sh
To better understand how this works, you can replace the three
Sample output
With
Use a "shebang" line
As this question points out, you should always use a "shebang" line for your bash scripts. So the first line would be:
#!/usr/bin/env bashPass values as arguments
Rather than prompting for the
SCALE value, it's generally better to use a command line argument. That way, the script can be reused by other shell scripts.Provide a stopping mechanism
As each term is calculated, eventually, it will be equal to zero given the passed
scale. This suggests a mechanism for stopping: check each term for 0 before adding it.Indent
do and while loopsI don't know of a bash style guide (there probably is one!) but I like to see the contents of loops indented to make it easier to read.
Putting it all together
Here's a modification of your script with all of these suggestions implemented:
bashpi.sh
#!/usr/bin/env bash
SCALE=$1
VALUE=2
PI=0
FITNESS=1
DELTA=3
while [ $(echo "$DELTA==0" |bc) != "1" ]
do
PI=$(echo "$PI+$DELTA" | bc)
DELTA=$(echo "scale=$SCALE;(4/($VALUE*($VALUE+1)*($VALUE+2)))-(4/(($VALUE+2)*($VALUE+3)*($VALUE+4)))" | bc)
VALUE=$(($VALUE+4))
FITNESS=$(($FITNESS+1))
echo "###############"
echo "--> $FITNESS // $VALUE"
echo "$PI"
doneTo better understand how this works, you can replace the three
echo statements with this one:echo "DELTA = ${DELTA} --> ${FITNESS} // ${VALUE} : ${PI}"Sample output
With
./bashpi.sh 4, and the modified echo above I get this output:DELTA = .1333 --> 2 // 6 : 3
DELTA = .0064 --> 3 // 10 : 3.1333
DELTA = .0012 --> 4 // 14 : 3.1397
DELTA = .0003 --> 5 // 18 : 3.1409
DELTA = .0001 --> 6 // 22 : 3.1412
DELTA = .0001 --> 7 // 26 : 3.1413
DELTA = .0001 --> 8 // 30 : 3.1414
DELTA = 0 --> 9 // 34 : 3.1415Code Snippets
#!/usr/bin/env bash#!/usr/bin/env bash
SCALE=$1
VALUE=2
PI=0
FITNESS=1
DELTA=3
while [ $(echo "$DELTA==0" |bc) != "1" ]
do
PI=$(echo "$PI+$DELTA" | bc)
DELTA=$(echo "scale=$SCALE;(4/($VALUE*($VALUE+1)*($VALUE+2)))-(4/(($VALUE+2)*($VALUE+3)*($VALUE+4)))" | bc)
VALUE=$(($VALUE+4))
FITNESS=$(($FITNESS+1))
echo "###############"
echo "--> $FITNESS // $VALUE"
echo "$PI"
doneecho "DELTA = ${DELTA} --> ${FITNESS} // ${VALUE} : ${PI}"DELTA = .1333 --> 2 // 6 : 3
DELTA = .0064 --> 3 // 10 : 3.1333
DELTA = .0012 --> 4 // 14 : 3.1397
DELTA = .0003 --> 5 // 18 : 3.1409
DELTA = .0001 --> 6 // 22 : 3.1412
DELTA = .0001 --> 7 // 26 : 3.1413
DELTA = .0001 --> 8 // 30 : 3.1414
DELTA = 0 --> 9 // 34 : 3.1415Context
StackExchange Code Review Q#94266, answer score: 13
Revisions (0)
No revisions yet.