Standard Library[lib]

C++ sqrt: square root with std::sqrt and cmath

Section
Standard Library [lib]
Standard
C++17
Compilers
MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2, Clang 23.1 (libc++)
Published
Length
6 min read
In this answer7 clauses
  1. 1What does sqrt return for an int, a float or a double?
  2. 2What does sqrt of a negative number return?
  3. 3How do you check for a perfect square in C++?
  4. 4Should you use sqrt or pow(x, 0.5)?
  5. 5How do you take a cube root or another root?
  6. 6How do you find a square root without sqrt?
  7. 7Which function for which root?

Abstract

std::sqrt from <cmath> returns the square root of a number: std::sqrt(25.0) is 5. A float gives a float and a double a double; an int is treated as a double, so the result is a double, and storing it in an int cuts the decimals off. A negative argument returns NaN, which std::isnan detects. std::cbrt takes cube roots, std::pow(x, 1.0 / n) other roots, and std::hypot the long side of a right triangle.

A square of five by five hatched cells drawn on a faint grid of unit squares; its bottom side is drawn thick in blue, with a blue dimension arrow beneath it measuring that side.
Figure 1 — The side of the square.

std::sqrt in C++ returns the square root of a number: std::sqrt(25.0) is 5. Include <cmath> to use it. Given an int, it returns a double, and given a negative number it returns NaN, “not a number”, which you test for with std::isnan. For a cube root, call std::cbrt.

A whole program that prints two square roots:

[Example 1:
#include <cmath>
#include <iostream>

int main() {
    std::cout << std::sqrt(25.0) << '\n';  // 5
    std::cout << std::sqrt(2.0) << '\n';   // 1.41421
}

— end example]

It printed:

[Example 2:
5
1.41421

— end example]

The first result is the double 5.0, which std::cout printed as 5, and it printed six digits of the second. The samples are C++17, built with MSVC 19.44, Clang 19.1 (MSVC STL), GCC 16.2 and Clang 23.1 (libc++). All four printed the same numbers; only the spelling of NaN differed. Since When lists, for each standard, the first compiler releases that support it.

Two hatched squares at one scale. Left, area 25: five by five unit cells, its side 5, std::sqrt(25.0). Right, area 2: over a faint two by two grid, covering one whole cell and parts of three, its side 1.41421…, std::sqrt(2.0).
Figure 2 — The square root of a number is the side of the square with that area.

What does sqrt return for an int, a float or a double?

For a float the sqrt function returns a float, and for a double a double. A whole number such as an int is treated as a double first (the standard’s <cmath> synopsis), so std::sqrt(10) returns a double as well. The samples checked each type with std::is_same_v, which is true when two types are the same:

[Example 3:
auto from_float = std::sqrt(2.0f);
auto from_double = std::sqrt(2.0);
auto from_int = std::sqrt(10);  // 10 becomes 10.0 first

std::cout << std::boolalpha;
std::cout << std::is_same_v<decltype(from_float), float> << '\n';
std::cout << std::is_same_v<decltype(from_double), double> << '\n';
std::cout << std::is_same_v<decltype(from_int), double> << '\n';
std::cout << from_int << '\n';  // 3.16228

int root = std::sqrt(10);  // the decimals are cut off
std::cout << root << '\n';  // 3

— end example]

All four printed true three times, then 3.16228 and 3. Storing the result in an int cuts the decimals off: 3.16228 became 3. Only MSVC warned (C4244 at /W4); GCC and both Clangs were silent at -Wall -Wextra. What an int and a double can each hold is in C++ data types.

What does sqrt of a negative number return?

NaN, a special value a double or a float can hold, meaning “not a number”. The program does not stop and no exception is thrown, so test the result with std::isnan, which returns true for a NaN. Better still, check the number before the call, so a negative one never reaches std::sqrt:

[Example 4:
double root = std::sqrt(-4.0);
std::cout << root << '\n';  // NaN, spelled by the library

std::cout << std::boolalpha;
std::cout << std::isnan(root) << '\n';  // true

double x = -4.0;
if (x < 0) {
    std::cout << "no real square root\n";
} else {
    std::cout << std::sqrt(x) << '\n';
}

— end example]

On Windows, MSVC and Clang 19.1 (both on Microsoft’s library) printed:

[Example 5:
-nan(ind)
true
no real square root

— end example]

GCC 16.2 and Clang 23.1 with libc++, both on Linux, printed -nan on the first line. The spelling belongs to the standard library, so never compare the printed text: call std::isnan.

How do you check for a perfect square in C++?

Take the square root, round it to the nearest whole number with std::lround, square that, and compare it with the number:

[Example 6:
bool is_perfect_square(int n) {
    if (n < 0) {
        return false;  // no negative number is a square
    }
    long long root = std::lround(std::sqrt(n));  // nearest whole
    return root * root == n;
}

int main() {
    std::cout << std::boolalpha;
    std::cout << is_perfect_square(49) << '\n';          // true
    std::cout << is_perfect_square(50) << '\n';          // false
    std::cout << is_perfect_square(2147395600) << '\n';  // true
}

— end example]

All four printed true, false and true. The rounded root goes in a long long because from 2,147,441,941 up it rounds to 46,341, whose square is too big for a 4-byte long, the type std::lround returns on Windows.

2,147,395,600 is 46,340 squared, the largest square a 4-byte int holds. The samples also ran the function over every square from 1 up to that one, 46,340 of them, and over each of them plus one: it answered correctly every time, on all four.

Should you use sqrt or pow(x, 0.5)?

Use std::sqrt: it says what it does. std::pow with an exponent of 0.5 is also a square root, and in the samples it gave exactly the same double:

[Example 7:
double by_sqrt = std::sqrt(x);
double by_pow = std::pow(x, 0.5);
// ...
std::cout << (by_sqrt == by_pow) << '\n';

— end example]

Printed with 17 significant digits, set with std::setprecision(17) as in formatting numbers with cout, and with std::boolalpha, all four gave for 2.0:

[Example 8:
1.4142135623730951
1.4142135623730951
true

— end example]

For 10.0 and 1e300 the two were equal too. That is what these builds did, not a promise: the IEEE floating-point standard requires std::sqrt to be correctly rounded, exact whenever the root can be held exactly in a double, and std::pow is “not so constrained” (cppreference on std::sqrt).

How do you take a cube root or another root?

Call std::cbrt for a cube root and std::pow(x, 1.0 / n) for the n-th root. Write 1.0, not 1: with an int n, 1 / n divides two whole numbers and gives 0, so std::pow(81.0, 1 / n) printed 1 on all four. For the long side of a right triangle, such as the diagonal of a 3 by 4 rectangle, std::hypot takes the two sides:

[Example 9:
std::cout << std::cbrt(27.0) << '\n';          // 3
std::cout << std::cbrt(-8.0) << '\n';          // -2
std::cout << std::pow(81.0, 1.0 / 4) << '\n';  // 3
std::cout << std::hypot(3.0, 4.0) << '\n';     // 5

— end example]

All four printed 3, -2, 3 and 5. std::cbrt accepts a negative number. std::pow with a negative base and a fractional exponent, such as 1.0 / 3, returns NaN instead, so take the cube root of a negative number with std::cbrt. std::hypot squares the sides for you, without undue overflow along the way, and since C++17 it takes a third argument, for a distance in three dimensions.

How do you find a square root without sqrt?

With Newton’s method: start from a guess, then replace it, round after round, with the average of the guess and the number divided by the guess:

[Example 10:
double x = 2.0;
double guess = 1.0;  // any positive start works
std::cout << std::setprecision(10);
for (int round = 1; round <= 6; ++round) {
    guess = (guess + x / guess) / 2;  // average of guess and x/guess
    std::cout << guess << '\n';
}
std::cout << std::sqrt(x) << '\n';

— end example]

It printed:

[Example 11:
1.5
1.416666667
1.414215686
1.414213562
1.414213562
1.414213562
1.414213562

— end example]

The fourth round already printed 1.414213562, the same ten digits as std::sqrt(2.0) on the last line, and rounds five and six changed nothing at that precision. It makes a good exercise; in code you ship, call std::sqrt.

Which function for which root?

You need Call
The square root std::sqrt(x)
The square root as a whole number std::lround(std::sqrt(x))
The cube root, negatives included std::cbrt(x)
The n-th root of a positive number std::pow(x, 1.0 / n)
The long side of a right triangle std::hypot(a, b)
To know whether a result is NaN std::isnan(result)

Standard library has the rest of the library’s answers.

Questions

How do you find the square root of a number in C++?

std::sqrt is declared in <cmath>: write #include <cmath> and call std::sqrt(x). The same header has std::isnan, which tests a result for NaN, and std::cbrt, the cube root.

What does sqrt return in C++?

A double for a double or a whole-number argument, a float for a float, and a long double for a long double. std::sqrt(10) returns the double 3.16228..., not an int. For a negative argument the value it returns is NaN, not a number.

What is the square root of a negative number in C++?

std::sqrt returns NaN, not a number, for an argument below zero, and the program keeps running. Test the result with std::isnan from <cmath>, or check that the number is not negative before the call. Do not compare the printed text: Microsoft's library prints -nan(ind), and GCC's library and libc++ on Linux print -nan.

How do you get a square root as an int in C++?

Round it with std::lround(std::sqrt(x)), which returns the nearest whole number as a long: 4 for 15. Assigning the result to an int, as in int root = std::sqrt(15);, cuts the decimals off instead and stores 3, the whole part.

What is the difference between sqrt, sqrtf and sqrtl?

sqrtf and sqrtl are the names C uses for the float and long double versions of sqrt, and C++ has them too, as std::sqrtf and std::sqrtl since C++11. In C++ you rarely need them: std::sqrt picks the float, double or long double version from the type of its argument.

Is std::sqrt constexpr?

From C++26 it is, so it can be evaluated at compile time. In C++17, C++20 and C++23 the standard does not declare it constexpr, so portable code cannot use it in a constant expression, such as the initializer of a constexpr variable.

Sources

  1. std::sqrt, std::sqrtf, std::sqrtlcppreference.com
  2. [cmath.syn] Header cmath synopsisC++ standard working draft
  3. std::isnancppreference.com
  4. std::round, std::lround, std::llroundcppreference.com
  5. std::powcppreference.com
  6. std::cbrtcppreference.com
  7. std::hypotcppreference.com

Read next

  1. C++ iterator: how begin() and end() workStandard Library · Miriam Castellanos · written for C++17
  2. Stack in C++: how std::stack works, with examplesStandard Library · Miriam Castellanos · written for C++17
  3. C++ string length: size(), length() and strlenStandard Library · Miriam Castellanos · written for C++17