I was blown away by the elegance and simplicity of the Babylonian Method to calculate a square root, which is the topic of this month’s Exercise. I only hope that my solution lives up the challenge, lest I suffer the fate of the Assyrians.
The challenge is to write the babylonian_sr() function, which consumes a double value and returns a double value, a square root. I set a precision value of seven and use the passed argument as the “high” value, 1.0 as the initial “low” value; refer to the original post if you’re confused by these labels. Here is my solution:
2022_04-Exercise.c
#include <stdio.h> double babylonian_sr(double root) { double low,high; int x; const int precision = 7; low = 1.0; high = root; for( x=0; x<precision; x++ ) { high = (high+low)/2.0; low = root/high; } return(low); } int main() { double pv,sr; printf("Enter a positive value: "); scanf("%lf",&pv); if( pv <= 0 ) return(1); sr = babylonian_sr(pv); printf("The square root of %.0f is %f\n", pv, sr ); return(0); }
My babylonian_sr() function uses variable names stolen from Figure 1 in the Exercise post: root
is the value passed; low
and high
are the less-than and greater-than values used in the average calculation.
The low
value is set to 1.0 at Line 9.
The high
value is set equal to root
at Line 10. Remember, root
doesn’t change throughout the function. (It could be declared const, but that’s just more typing.)
Variable x
in the for loop sets the precision, the number of times the two steps repeat. I chose the precision value 7, set at Line 7.
Step 1 takes place at Line 13. The new high
value is determined as the average of high
and low
.
Step 2 takes place at Line 14. The new low
value is calculated as the original number, root
, divided by high
.
The process repeats precision
times, and the result stored in low
is returned at Line 16.
Here’s a sample run:
Enter a positive value: 5
The square root of 5 is 2.236068
For some large values, the result may not be perfect. If you find such an issue, increase the value of variable precision
to something greater than seven, but keep in mind that floating point values aren’t precise.
If you really want to test your babylonian_sr() function solution, add statements in the main() function that compare your function’s output with C’s sqrt() function. Remember to include the math.h
header, and if you use Linux, you must link in the m
library to build the code.
It might be interesting to output low in each iteration of the loop to see how it converges on the result. What happens if you pass a number between 0 and 1, so high would be < low?
I didn’t try fractions, but you’re correct, it would be interesting to see how they work.
When I originally coded the program, I had a printf() statement output the values of each variable (
low
,high
) for each iteration. I forget the results, but it’s a fun algorithm.