Square Root upto Given Precision using Binary Search

Last Updated : 25 Jul, 2026

Given a positive number n and an integer p representing the desired precision, compute the square root of n accurate to p decimal places. The solution should avoid using built-in square root functions.
Note: Precision control is required to ensure the output is correctly rounded or truncated at p digits after the decimal.

Examples: 

Input: n = 50, p = 3
Output: 7.071
Explanation: The square root of 50 up to 3 decimal places is 7.071

Input: n = 10, p = 4
Output: 3.1622
Explanation: The square root of 10 up to 4 decimal places is 3.1622

Try It Yourself
redirect icon

[Expected Approach] Binary Search with Incremental Refinement - O(log n + p) Time and O(1) Space

The integer part of the square root is found first via binary search. Each decimal digit is then determined one at a time by testing whether adding a shrinking increment still keeps the square within n.

Step-by-Step Illustration:

Finding the integer part:

  • start = 0, end = 50, ans = 0
  • mid = 25 -> 25×25 = 625 > 50 -> end = 24
  • mid = 12 -> 12×12 = 144 > 50 -> end = 11
  • mid = 5 -> 5×5 = 25 ≤ 50 -> ans = 5, start = 6
  • mid = 8 -> 8×8 = 64 > 50 -> end = 7
  • mid = 6 -> 6×6 = 36 ≤ 50 -> ans = 6, start = 7
  • mid = 7 -> 7×7 = 49 ≤ 50 -> ans = 7, start = 8
  • start (8) > end (7), loop ends -> ans = 7

Refining digit 1 (increment = 0.1):

  • (7 + 0.1)2 = 7.12 = 50.41 > 50 -> stop, ans stays 7
  • increment becomes 0.01

Refining digit 2 (increment = 0.01):

  • (7 + 0.01)2 = 7.012 = 49.14 ≤ 50 -> ans = 7.01
  • (7.02)2 = 49.28 ≤ 50 -> ans = 7.02
  • ... continues adding 0.01 ...
  • (7.07)2 = 49.98 ≤ 50 -> ans = 7.07
  • (7.08)2 = 50.13 > 50 -> stop, ans stays 7.07
  • increment becomes 0.001

Refining digit 3 (increment = 0.001):

  • (7.071)2 = 49.999 ≤ 50 -> ans = 7.071
  • (7.072)2 = 50.013 > 50 -> stop, ans stays 7.071
  • increment becomes 0.0001, loop ends (p = 3 digits done)

Final answer: 7.071

C++
#include <bits/stdc++.h>
using namespace std;

double squareRoot(int n, int p) {
    int start = 0, end = n;
    double ans = 0.0;

    // binary search for the integer part of the square root
    while (start <= end) {
        int mid = start + (end - start) / 2;

        if ((long long)mid * mid <= n) {
            ans = mid;
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }

    // refine the decimal part one digit at a time
    double increment = 0.1;
    for (int i = 0; i < p; i++) {
        while ((ans + increment) * (ans + increment) <= n) {
            ans += increment;
        }
        increment /= 10;
    }

    return ans;
}

int main() {
    int n = 50, p = 3;

    cout << fixed << setprecision(3) << squareRoot(n, p) << endl;

    return 0;
}
Java
class GfG {
    static double squareRoot(int n, int p) {
        int start = 0, end = n;
        double ans = 0.0;

        // binary search for the integer part of the square root
        while (start <= end) {
            int mid = start + (end - start) / 2;

            if ((long) mid * mid <= n) {
                ans = mid;
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }

        // refine the decimal part one digit at a time
        double increment = 0.1;
        for (int i = 0; i < p; i++) {
            while ((ans + increment) * (ans + increment) <= n) {
                ans += increment;
            }
            increment /= 10;
        }

        return ans;
    }

    public static void main(String[] args) {
        int n = 50, p = 3;

        System.out.printf("%.3f%n", squareRoot(n, p));
    }
}
Python
def squareRoot(n, p):
    start, end = 0, n
    ans = 0.0

    # binary search for the integer part of the square root
    while start <= end:
        mid = start + (end - start) // 2

        if mid * mid <= n:
            ans = mid
            start = mid + 1
        else:
            end = mid - 1

    # refine the decimal part one digit at a time
    increment = 0.1
    for i in range(p):
        while (ans + increment) * (ans + increment) <= n:
            ans += increment
        increment /= 10

    return ans

n, p = 50, 3
print(f"{squareRoot(n, p):.3f}")
C#
using System;

class GfG {
    static double squareRoot(int n, int p) {
        int start = 0, end = n;
        double ans = 0.0;

        // binary search for the integer part of the square root
        while (start <= end) {
            int mid = start + (end - start) / 2;

            if ((long)mid * mid <= n) {
                ans = mid;
                start = mid + 1;
            } else {
                end = mid - 1;
            }
        }

        // refine the decimal part one digit at a time
        double increment = 0.1;
        for (int i = 0; i < p; i++) {
            while ((ans + increment) * (ans + increment) <= n) {
                ans += increment;
            }
            increment /= 10;
        }

        return ans;
    }

    static void Main() {
        int n = 50, p = 3;

        Console.WriteLine(squareRoot(n, p).ToString("F3"));
    }
}
JavaScript
function squareRoot(n, p) {
    let start = 0, end = n;
    let ans = 0.0;

    // binary search for the integer part of the square root
    while (start <= end) {
        const mid = start + Math.floor((end - start) / 2);

        if (mid * mid <= n) {
            ans = mid;
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }

    // refine the decimal part one digit at a time
    let increment = 0.1;
    for (let i = 0; i < p; i++) {
        while ((ans + increment) * (ans + increment) <= n) {
            ans += increment;
        }
        increment /= 10;
    }

    return ans;
}

// Driver Code
const n = 50, p = 3;
console.log(squareRoot(n, p).toFixed(3));

Output
7.071

[Alternate Approach] Binary Search on Floating-Point Numbers - O(log(n/eps)) Time and O(1) Space

Instead of building the answer digit by digit, binary search is run directly on real numbers between 0 and n, narrowing the range until it converges to the square root. A fixed number of iterations ensures enough precision, and the result is then truncated to the required decimal places, with perfect squares handled separately using exact integer arithmetic to avoid floating-point boundary errors.

Step-by-Step Illustration:

Step 1: Check if n is a perfect square (integer arithmetic only)

  • Compute floor(√50) using integer binary search → 7
  • Check 7×7 = 49 ≠ 50 -> not a perfect square, proceed to binary search on doubles

Step 2: Binary search on doubles (low = 0, high = 50)

  • Iteration 1: mid = 25.0, mid2 = 625.0 > 50 -> high = 25.0
  • Iteration 2: mid = 12.5, mid2 = 156.25 > 50 -> high = 12.5
  • Iteration 3: mid = 6.25, mid2 = 39.06 < 50 -> low = 6.25
  • Iteration 4: mid = 9.375, mid2 = 87.89 > 50 -> high = 9.375
  • Iteration 5: mid = 7.8125, mid2 = 61.04 > 50 -> high = 7.8125
  • ... the interval keeps halving, narrowing in on 7.0710678... ...
  • After 200 iterations (a fixed count, far more than needed), low and high have converged to within an extremely tiny gap of the true value

Step 3: Truncate to p = 3 decimal places

  • Take the converged low value ≈ 7.0710678...
  • Multiply by 1000 -> 7071.0678...
  • Floor -> 7071
  • Divide by 1000 -> 7.071

Final answer: 7.071

C++
#include <bits/stdc++.h>
using namespace std;

// finds floor(sqrt(n)) using pure integer binary search, no built-in sqrt function
long long integerSqrt(long long n) {
    long long low = 0, high = n, ans = 0;

    while (low <= high) {
        long long mid = low + (high - low) / 2;

        if (mid * mid <= n) {
            ans = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    return ans;
}

double squareRoot(int n, int p) {
    // check for a perfect square first using exact integer arithmetic
    long long intRoot = integerSqrt(n);
    if (intRoot * intRoot == n) {
        return (double) intRoot;
    }

    double low = 0.0, high = n;

    // fixed iteration count converges far beyond any precision p could require
    for (int i = 0; i < 200; i++) {
        double mid = (low + high) / 2.0;

        if (mid * mid < n) {
            low = mid;
        } else {
            high = mid;
        }
    }

    // truncate to p decimal places using integer arithmetic
    double factor = pow(10, p);
    double truncated = floor(low * factor) / factor;

    return truncated;
}

int main() {
    int n = 50, p = 3;

    cout << fixed << setprecision(3) << squareRoot(n, p) << endl;

    return 0;
}
Java
class GfG {
    // finds floor(sqrt(n)) using pure integer binary search, no built-in sqrt function
    static long integerSqrt(long n) {
        long low = 0, high = n, ans = 0;

        while (low <= high) {
            long mid = low + (high - low) / 2;

            if (mid * mid <= n) {
                ans = mid;
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return ans;
    }

    static double squareRoot(int n, int p) {
        // check for a perfect square first using exact integer arithmetic
        long intRoot = integerSqrt(n);
        if (intRoot * intRoot == n) {
            return (double) intRoot;
        }

        double low = 0.0, high = n;

        // fixed iteration count converges far beyond any precision p could require
        for (int i = 0; i < 200; i++) {
            double mid = (low + high) / 2.0;

            if (mid * mid < n) {
                low = mid;
            } else {
                high = mid;
            }
        }

        // truncate to p decimal places using integer arithmetic
        double factor = Math.pow(10, p);
        double truncated = Math.floor(low * factor) / factor;

        return truncated;
    }

    public static void main(String[] args) {
        int n = 50, p = 3;

        System.out.printf("%.3f%n", squareRoot(n, p));
    }
}
Python
def integerSqrt(n):
    # finds floor(sqrt(n)) using pure integer binary search, no built-in sqrt function
    low, high, ans = 0, n, 0

    while low <= high:
        mid = low + (high - low) // 2

        if mid * mid <= n:
            ans = mid
            low = mid + 1
        else:
            high = mid - 1

    return ans

def squareRoot(n, p):
    # check for a perfect square first using exact integer arithmetic
    intRoot = integerSqrt(n)
    if intRoot * intRoot == n:
        return float(intRoot)

    low, high = 0.0, float(n)

    # fixed iteration count converges far beyond any precision p could require
    for i in range(200):
        mid = (low + high) / 2.0

        if mid * mid < n:
            low = mid
        else:
            high = mid

    # truncate to p decimal places using integer arithmetic
    factor = 10 ** p
    truncated = int(low * factor) / factor

    return truncated

n, p = 50, 3
print(f"{squareRoot(n, p):.3f}")
C#
using System;

class GfG {
    // finds floor(sqrt(n)) using pure integer binary search, no built-in sqrt function
    static long integerSqrt(long n) {
        long low = 0, high = n, ans = 0;

        while (low <= high) {
            long mid = low + (high - low) / 2;

            if (mid * mid <= n) {
                ans = mid;
                low = mid + 1;
            } else {
                high = mid - 1;
            }
        }

        return ans;
    }

    static double squareRoot(int n, int p) {
        // check for a perfect square first using exact integer arithmetic
        long intRoot = integerSqrt(n);
        if (intRoot * intRoot == n) {
            return (double) intRoot;
        }

        double low = 0.0, high = n;

        // fixed iteration count converges far beyond any precision p could require
        for (int i = 0; i < 200; i++) {
            double mid = (low + high) / 2.0;

            if (mid * mid < n) {
                low = mid;
            } else {
                high = mid;
            }
        }

        // truncate to p decimal places using integer arithmetic
        double factor = Math.Pow(10, p);
        double truncated = Math.Floor(low * factor) / factor;

        return truncated;
    }

    static void Main() {
        int n = 50, p = 3;

        Console.WriteLine(squareRoot(n, p).ToString("F3"));
    }
}
JavaScript
// finds floor(sqrt(n)) using pure integer binary search, no built-in sqrt function
function integerSqrt(n) {
    let low = 0, high = n, ans = 0;

    while (low <= high) {
        const mid = low + Math.floor((high - low) / 2);

        if (mid * mid <= n) {
            ans = mid;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    return ans;
}

function squareRoot(n, p) {
    // check for a perfect square first using exact integer arithmetic
    const intRoot = integerSqrt(n);
    if (intRoot * intRoot === n) {
        return intRoot;
    }

    let low = 0.0, high = n;

    // fixed iteration count converges far beyond any precision p could require
    for (let i = 0; i < 200; i++) {
        const mid = (low + high) / 2.0;

        if (mid * mid < n) {
            low = mid;
        } else {
            high = mid;
        }
    }

    // truncate to p decimal places using integer arithmetic
    const factor = Math.pow(10, p);
    const truncated = Math.floor(low * factor) / factor;

    return truncated;
}

// Driver Code
const n = 50, p = 3;
console.log(squareRoot(n, p).toFixed(3));

Output
7.071
Comment