In C++11 is sqrt defined as constexpr?
In C++11 is std::sqrt
defined as constexpr
, i.e. can it legally be used from other constexpr
functions or in compile-time contexts like array sizes or template arguments? g++ seems to allow it (using -std=c++0x
), but I'm not sure I can take that as authoritative given that c++0x/c++11 support is still incomplete. The fact that I can't seem to find anything on the Internet makes me unsure.
It seems like this should be something one could easily find out using Google, but I've tried (for 40 minutes now...) and couldn't find anything. I could find several proposals for adding constexpr to various parts of the standard library (like for example this one), but nothing about sqrt
or other math functions.
std::sqrt
is not defined as constexpr
, according to section 26.8 of N3291: the C++11 FDIS (and I doubt they added it to the final standard after that). One could possibly write such a version, but the standard library version is not constexpr
.
Just in case anyone is interested in a meta integer square root function, here is one I wrote while a ago:
constexpr std::size_t isqrt_impl
(std::size_t sq, std::size_t dlt, std::size_t value){
return sq <= value ?
isqrt_impl(sq+dlt, dlt+2, value) : (dlt >> 1) - 1;
}
constexpr std::size_t isqrt(std::size_t value){
return isqrt_impl(1, 3, value);
}
Here is a fast and efficient constexpr implementation for double
floating point numbers. You may adapt it to float
too, if needed:
#include <limits>
namespace Detail
{
double constexpr sqrtNewtonRaphson(double x, double curr, double prev)
{
return curr == prev
? curr
: sqrtNewtonRaphson(x, 0.5 * (curr + x / curr), curr);
}
}
/*
* Constexpr version of the square root
* Return value:
* - For a finite and non-negative value of "x", returns an approximation for the square root of "x"
* - Otherwise, returns NaN
*/
double constexpr sqrt(double x)
{
return x >= 0 && x < std::numeric_limits<double>::infinity()
? Detail::sqrtNewtonRaphson(x, x, 0)
: std::numeric_limits<double>::quiet_NaN();
}