-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnaisqrt.hpp
42 lines (32 loc) · 828 Bytes
/
naisqrt.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef INTT_ARITH_NAISQRT_HPP
# define INTT_ARITH_NAISQRT_HPP
# pragma once
#include "arith.hpp"
namespace ar
{ // provides naive implementations of sqrt
constexpr auto&& seqsqrt(uarray_c auto&& a) noexcept
{ // CR = CR + (N * wbits - CR) / 2;
using T = std::remove_cvref_t<decltype(a[0])>;
enum : std::size_t { N = size<decltype(a)>(), M = 2 * N };
enum : std::size_t { bits = bit_size_v<decltype(a)> };
array_t<T, M> r;
auto const CR((bits + clz(a)) / 2);
lshl(copy(r, a), CR);
array_t<T, M> Q{};
for (auto i(2 * bits - CR); bits != i;)
{
if (ucmp(lshl<1>(r), set_bit(lshl<1>(Q), --i)) >= 0)
{
sub(r, Q);
set_bit(lshr<1>(clear_bit(Q, i)), i);
}
else
{
lshr<1>(clear_bit(Q, i));
}
}
//
return rcopy<N - 1>(a, Q);
}
}
#endif // INTT_ARITH_NAISQRT_HPP