patterncppMinor
Compile time integer square root for large numbers
Viewed 0 times
compilenumberstimelargerootforsquareinteger
Problem
This computes the integer square root at compile time for any \$0 \le N \le L\$ where \$L\$ is the largest integral representation of template parameter
This was motivated by the fact that many of the algorithms I found were not able to handle large values of \$N\$. I also just wanted to practice template meta-programming.
Important: I cannot simply declare the runtime algorithm as a
The implementation is based on this runtime algorithm:
Source
square_root.h
Template meta-programming based implementation of the algorithm:
main.cpp
Some tests, compilati
T.This was motivated by the fact that many of the algorithms I found were not able to handle large values of \$N\$. I also just wanted to practice template meta-programming.
Important: I cannot simply declare the runtime algorithm as a
constexpr function because my compiler does not allow it.The implementation is based on this runtime algorithm:
template
T rt_square_root( T num )
{
T bit{ static_cast( 1 ) num )
bit >>= 2;
T res{ 0 };
while ( bit )
{
T delta{ res + bit };
if ( num >= delta )
{
num -= delta;
res = ( res >> 1 ) + bit;
}
else
{
res >>= 1;
}
bit >>= 2;
}
return res;
}Source
square_root.h
Template meta-programming based implementation of the algorithm:
#ifndef CR_SQUARE_ROOT_H
#define CR_SQUARE_ROOT_H
namespace ct
{
template
bool constexpr greater( T a, U b )
{
return b
class calc_shifted_bit
{
private:
static T constexpr shifted_bit = bit >> 2;
public:
static T constexpr result = calc_shifted_bit::result;
};
template
class calc_shifted_bit
{
public:
static T constexpr result = bit
class calc_sqrt
{
private:
static T constexpr delta = res + bit;
static bool constexpr num_gt_delta = num >= delta;
public:
static T constexpr result = calc_sqrt
> 1 ) + bit : ( res >> 1 ),
( bit >> 2 )
>::result;
};
template
class calc_sqrt>
{
public:
static T constexpr result = res;
};
template
struct sqrt
{
static T constexpr result =
calc_sqrt
( 1 ) ::result
>::result;
};
}main.cpp
Some tests, compilati
Solution
Since you're on a C++14 compiler, the simplest solution is just to stick
I'm not sure there's a compelling reason to do it any other way.
constexpr in front of your runtime algorithm:template
constexpr T rt_square_root(T num)
{
/* exact same code as before */
}
static_assert( rt_square_root(N_1 * N_1) == N_1, "bad square root" );I'm not sure there's a compelling reason to do it any other way.
Code Snippets
template <typename T>
constexpr T rt_square_root(T num)
{
/* exact same code as before */
}
static_assert( rt_square_root(N_1 * N_1) == N_1, "bad square root" );Context
StackExchange Code Review Q#109604, answer score: 3
Revisions (0)
No revisions yet.