sqrt_double.cpp 1.2 KB
Newer Older
1 2 3 4 5 6 7 8 9
/**
 * @file
 * @brief Calculate the square root of any positive real 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
 */
D
DarkWarrior703 已提交
10
#include <cassert>
11
#include <iostream>
D
DarkWarrior703 已提交
12

13 14 15 16 17 18
/** 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);
19
    }
20 21 22
    double l = 0, r = a;
    /* Epsilon is the precision.
    A great precision is
D
DarkWarrior703 已提交
23
    between 1e-7 and 1e-12.
D
DarkWarrior703 已提交
24
    double epsilon = 1e-12;
D
DarkWarrior703 已提交
25
    */
D
DarkWarrior703 已提交
26
    double epsilon = 1e-12;
27
    while (l <= r) {
D
DarkWarrior703 已提交
28
        double mid = (l + r) / 2;
29
        if (mid * mid > a) {
D
DarkWarrior703 已提交
30
            r = mid;
D
DarkWarrior703 已提交
31
        } else {
32
            if (a - mid * mid < epsilon) {
D
DarkWarrior703 已提交
33 34 35 36 37 38 39
                return mid;
            }
            l = mid;
        }
    }
    return -1;
}
40 41

/** main function */
D
DarkWarrior703 已提交
42
int main() {
43 44 45 46 47 48
    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);
D
DarkWarrior703 已提交
49
}