barretenberg
Loading...
Searching...
No Matches
get_msb.hpp
1#pragma once
2#include <array>
3#include <cstddef>
4#include <cstdint>
5namespace numeric {
6
7// from http://supertech.csail.mit.edu/papers/debruijn.pdf
8constexpr inline uint32_t get_msb32(const uint32_t in)
9{
10 constexpr std::array<uint8_t, 32> MultiplyDeBruijnBitPosition{ 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16,
11 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17,
12 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
13
14 uint32_t v = in | (in >> 1);
15 v |= v >> 2;
16 v |= v >> 4;
17 v |= v >> 8;
18 v |= v >> 16;
19
20 return MultiplyDeBruijnBitPosition[static_cast<uint32_t>(v * static_cast<uint32_t>(0x07C4ACDD)) >>
21 static_cast<uint32_t>(27)];
22}
23
24constexpr inline uint64_t get_msb64(const uint64_t in)
25{
26 constexpr std::array<uint8_t, 64> de_bruijn_sequence{ 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28,
27 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32,
28 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15,
29 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33,
30 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63 };
31
32 uint64_t t = in | (in >> 1);
33 t |= t >> 2;
34 t |= t >> 4;
35 t |= t >> 8;
36 t |= t >> 16;
37 t |= t >> 32;
38 return static_cast<uint64_t>(de_bruijn_sequence[(t * 0x03F79D71B4CB0A89ULL) >> 58ULL]);
39};
40
41template <typename T> constexpr inline T get_msb(const T in)
42{
43 return (sizeof(T) <= 4) ? get_msb32(in) : get_msb64(in);
44}
45
46} // namespace numeric
Definition: field2_declarations.hpp:6