Hi all...
This is just a fun project to see if it is possible to get a square root of a positive integer from 1 to 9200000 to 6 decimal places on a 64 bit architecture machine.
It is coded around dash and the results show the values from 0 to 10000.
Complex numbers can easily be catered for by taking the absolute value of the negative integer and placing the letter i at the end of the result(s).
Enjoy ripping it apart...
#!/usr/local/bin/dash
# sqrt_dash.sh
# Usage: [/full/path/to/][./]sqrt_dash.sh <integer_from_1_to_9200000>
# Fully POSIX compliant.
# Checked against Google for many values.
#
# Newton method integer maths only, POSIX compliant shell, (dash).
# Maximum positive integer, 64 bits, 9,223,372,036,854,775,807.
# Returns the square root of integer numbers from 1 to just over 9200000 to 6 places of decimals.
#
# Maximum positive integer, 32 bits, 2,147,483,647.
# Returns the square root of integer numbers from 1 to just over 2000 to 3 places of decimals.
#
# This is for 64 bit systems.
# Commented out is for 32 bit systems.
NUMBER=${1}
if [ ${NUMBER} -eq 0 ]
then
# 32 bit systems.
# echo "0.000"
# 64 bit systems.
echo "0.000000"
exit
fi
# 32 bit systems.
# NUMBER=$(( NUMBER * 1000000 ))
# 64 bit systems.
NUMBER=$(( NUMBER * 1000000000000 ))
APPROX=$(( NUMBER / 2 ))
CLOSER=$(( (APPROX + NUMBER / APPROX) / 2 ))
while [ ${CLOSER} -ne ${APPROX} ]
do
APPROX=${CLOSER}
CLOSER=$(( (APPROX + NUMBER / APPROX) / 2 ))
done
# 32 bit systems.
# printf "%.3f\n" $(( APPROX ))e-3
# 64 bit systems.
printf "%f\n" $(( APPROX ))e-6
Results for numbers 0 to 10000 timed. OSX 10.14.6, default bash terminal.
Last login: Thu Oct 10 16:51:21 on ttys000
AMIGA:amiga~> cd desktop/Code/Shell
AMIGA:amiga~/desktop/Code/Shell> time for n in {0..10000}; do ./sqrt_dash.sh $n; done
0.000000
1.000000
1.414213
1.732050
2.000000
2.236067
2.449489
2.645751
2.828427
3.000000
3.162277
3.316624
3.464101
3.605551
3.741657
3.872983
4.000000
4.123105
4.242640
4.358898
........
........
99.879927
99.884933
99.889939
99.894944
99.899949
99.904954
99.909959
99.914963
99.919967
99.924971
99.929975
99.934978
99.939981
99.944984
99.949987
99.954989
99.959991
99.964993
99.969995
99.974996
99.979997
99.984998
99.989999
99.994999
100.000000
real 0m48.412s
user 0m18.066s
sys 0m18.601s
AMIGA:amiga~/desktop/Code/Shell> _
I showed it to the wife and I said 'what sticks out the most?'
She said the 'pink obviously!'
Anyhow here is an add-on to get Fixed Point Numbers SQRT from .100 to 9200000.000 using 'sqrt_bash.sh' edited to 32 bit mode.
All entries MUST be Fixed Point values even if they end in ?.000...
#!/usr/local/bin/dash
# FP_sqrt.sh
#
# Requires sqrt_dash.sh to work.
# This MUST be 3 decimal places only using 'sqrt_bash.sh' in 32 bit mode running in 64 bit.
#
# Usage: [full/path/to/][./]FP_sqrt.sh <.100_to_a_little_over_9200000.000>
#
# Note: numbers below 1.000 the input must be .??? format without the leading zero.
# The errors below .100 grow exponentially so values cannot to be trusted.
NUMBER=${1}
# Step 1, allocate this to _fractional_ part.
FRACT="${NUMBER##*.}"
# Step 2, get _whole_number_ part.
WHOLE="${NUMBER%%.*}"
# Step 3, put WHOLE and FRACT together and include 3 zeros.
NUMBER="${WHOLE}${FRACT}"'000'
# Step 4, call "sqrt_dash.sh" with new NUMBER into a variable.
NUMBER=$( ./sqrt_dash.sh "${NUMBER}" )
printf "%.3f\n" ${NUMBER}e-3
Results, confirmed by Google. Same MBP platform as always.
Neat, not an integer shell version though. It would be interesting if someone else has actually done it...
Working on Nth root at the moment, but I suspect it will be a step too far for a POSIX shell.