Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
get_msb.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Luke], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8#include <array>
9#include <cassert>
10#include <cstddef>
11#include <cstdint>
12#include <limits>
13namespace bb::numeric {
14
15// from http://supertech.csail.mit.edu/papers/debruijn.pdf
16constexpr inline uint32_t get_msb32(const uint32_t in)
17{
18 constexpr std::array<uint8_t, 32> MultiplyDeBruijnBitPosition{ 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16,
19 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17,
20 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
21
22 uint32_t v = in | (in >> 1);
23 v |= v >> 2;
24 v |= v >> 4;
25 v |= v >> 8;
26 v |= v >> 16;
27
28 return MultiplyDeBruijnBitPosition[static_cast<uint32_t>(v * static_cast<uint32_t>(0x07C4ACDD)) >>
29 static_cast<uint32_t>(27)];
30}
31
32constexpr inline uint64_t get_msb64(const uint64_t in)
33{
34 constexpr std::array<uint8_t, 64> de_bruijn_sequence{ 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28,
35 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32,
36 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15,
37 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33,
38 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63 };
39
40 uint64_t t = in | (in >> 1);
41 t |= t >> 2;
42 t |= t >> 4;
43 t |= t >> 8;
44 t |= t >> 16;
45 t |= t >> 32;
46 return static_cast<uint64_t>(de_bruijn_sequence[(t * 0x03F79D71B4CB0A89ULL) >> 58ULL]);
47};
48
49template <typename T> constexpr inline T get_msb(const T in)
50{
51 return (sizeof(T) <= 4) ? get_msb32(in) : get_msb64(in);
52}
53
54constexpr inline uint32_t get_lsb32(const uint32_t in)
55{
56 if (in == 0) {
57 return 0;
58 }
59 return static_cast<uint32_t>(__builtin_ctz(in));
60}
61
62constexpr inline uint64_t get_lsb64(const uint64_t in)
63{
64 if (in == 0) {
65 return 0;
66 }
67 return static_cast<uint64_t>(__builtin_ctzll(in));
68}
69
70template <typename T> constexpr inline T get_lsb(const T in)
71{
72 return (sizeof(T) <= 4) ? get_lsb32(in) : get_lsb64(in);
73}
74
75template <typename T> constexpr inline T round_up_power_2(const T in)
76{
77 if (in == 0) {
78 return 0;
79 }
80 auto lower_bound = T(1) << get_msb(in);
81 if (lower_bound == in) {
82 return in;
83 }
84 // Overflow check: lower_bound is the highest power of 2 <= in,
85 // so lower_bound * 2 would overflow if lower_bound is already the top bit.
86 assert(lower_bound <= (std::numeric_limits<T>::max() >> 1));
87 return lower_bound * 2;
88}
89
90} // namespace bb::numeric
constexpr uint32_t get_lsb32(const uint32_t in)
Definition get_msb.hpp:54
constexpr uint64_t get_msb64(const uint64_t in)
Definition get_msb.hpp:32
constexpr T get_msb(const T in)
Definition get_msb.hpp:49
constexpr T round_up_power_2(const T in)
Definition get_msb.hpp:75
constexpr T get_lsb(const T in)
Definition get_msb.hpp:70
constexpr uint32_t get_msb32(const uint32_t in)
Definition get_msb.hpp:16
constexpr uint64_t get_lsb64(const uint64_t in)
Definition get_msb.hpp:62