diff --git a/math/sqrt_double.cpp b/math/sqrt_double.cpp index 5a0fd1c88..1521b500a 100644 --- a/math/sqrt_double.cpp +++ b/math/sqrt_double.cpp @@ -1,27 +1,35 @@ -#include +/** + * @file + * @brief Calculate the square root of any positive number in \f$O(\log N)\f$ + * time, with precision fixed using [bisection + * method](https://en.wikipedia.org/wiki/Bisection_method) of root-finding. + * + * @see Can be implemented using faster and better algorithms like + * newton_raphson_method.cpp and false_position.cpp + */ #include +#include -/* Calculate the square root of any -number in O(logn) time, -with precision fixed */ - -double Sqrt(double x) { - if ( x > 0 && x < 1 ) { - return 1/Sqrt(1/x); +/** Bisection method implemented for the function \f$x^2-a=0\f$ + * whose roots are \f$\pm\sqrt{a}\f$ and only the positive root is returned. + */ +double Sqrt(double a) { + if (a > 0 && a < 1) { + return 1 / Sqrt(1 / a); } - double l = 0, r = x; - /* Epsilon is the precision. - A great precision is + double l = 0, r = a; + /* Epsilon is the precision. + A great precision is between 1e-7 and 1e-12. double epsilon = 1e-12; */ double epsilon = 1e-12; - while ( l <= r ) { + while (l <= r) { double mid = (l + r) / 2; - if ( mid * mid > x ) { + if (mid * mid > a) { r = mid; } else { - if ( x - mid * mid < epsilon ) { + if (a - mid * mid < epsilon) { return mid; } l = mid; @@ -29,11 +37,13 @@ double Sqrt(double x) { } return -1; } + +/** main function */ int main() { - double n{}; - std::cin >> n; - assert(n >= 0); - // Change this line for a better precision - std::cout.precision(12); - std::cout << std::fixed << Sqrt(n); + double n{}; + std::cin >> n; + assert(n >= 0); + // Change this line for a better precision + std::cout.precision(12); + std::cout << std::fixed << Sqrt(n); }