BitStream
bounded_range.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4  * Copyright (c) 2018 Stanislav Denisov
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include <cstdint>
26 
27 namespace bitstream
28 {
33  {
34  public:
35  constexpr bounded_range() noexcept :
36  m_Min(0),
37  m_Max(0),
38  m_Precision(0),
39  m_BitsRequired(0),
40  m_Mask(0) {}
41 
42  constexpr bounded_range(float min, float max, float precision) noexcept :
43  m_Min(min),
44  m_Max(max),
45  m_Precision(precision),
46  m_BitsRequired(log2(static_cast<uint32_t>((m_Max - m_Min) * (1.0f / precision) + 0.5f)) + 1),
47  m_Mask((1U << m_BitsRequired) - 1U) {}
48 
49  constexpr inline float get_min() const noexcept { return m_Min; }
50  constexpr inline float get_max() const noexcept { return m_Max; }
51  constexpr inline float get_precision() const noexcept { return m_Precision; }
52  constexpr inline uint32_t get_bits_required() const noexcept { return m_BitsRequired; }
53 
54  constexpr inline uint32_t quantize(float value) const noexcept
55  {
56  if (value < m_Min)
57  value = m_Min;
58  else if (value > m_Max)
59  value = m_Max;
60 
61  return static_cast<uint32_t>(static_cast<float>((value - m_Min) * (1.0f / m_Precision)) + 0.5f) & m_Mask;
62  }
63 
64  constexpr inline float dequantize(uint32_t data) const noexcept
65  {
66  float adjusted = (static_cast<float>(data) * m_Precision) + m_Min;
67 
68  if (adjusted < m_Min)
69  adjusted = m_Min;
70  else if (adjusted > m_Max)
71  adjusted = m_Max;
72 
73  return adjusted;
74  }
75 
76  private:
77  constexpr inline static uint32_t log2(uint32_t value) noexcept
78  {
79  value |= value >> 1;
80  value |= value >> 2;
81  value |= value >> 4;
82  value |= value >> 8;
83  value |= value >> 16;
84 
85  return DE_BRUIJN[(value * 0x07C4ACDDU) >> 27];
86  }
87 
88  private:
89  float m_Min;
90  float m_Max;
91  float m_Precision;
92 
93  uint32_t m_BitsRequired;
94  uint32_t m_Mask;
95 
96  constexpr inline static uint32_t DE_BRUIJN[32]
97  {
98  0, 9, 1, 10, 13, 21, 2, 29,
99  11, 14, 16, 18, 22, 25, 3, 30,
100  8, 12, 20, 28, 15, 17, 24, 7,
101  19, 27, 23, 6, 26, 5, 4, 31
102  };
103  };
104 }
Class for quantizing single-precision floats into a range and precision.
Definition: bounded_range.h:33
constexpr uint32_t quantize(float value) const noexcept
Definition: bounded_range.h:54
constexpr float dequantize(uint32_t data) const noexcept
Definition: bounded_range.h:64
constexpr float get_max() const noexcept
Definition: bounded_range.h:50
constexpr bounded_range(float min, float max, float precision) noexcept
Definition: bounded_range.h:42
constexpr float get_min() const noexcept
Definition: bounded_range.h:49
constexpr uint32_t get_bits_required() const noexcept
Definition: bounded_range.h:52
constexpr bounded_range() noexcept
Definition: bounded_range.h:35
constexpr float get_precision() const noexcept
Definition: bounded_range.h:51
Definition: bounded_range.h:28