Embedded Template Library 1.0
Loading...
Searching...
No Matches
scaled_rounding.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2018 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_SCALED_ROUNDING_INCLUDED
32#define ETL_SCALED_ROUNDING_INCLUDED
33
34#include "platform.h"
35#include "absolute.h"
36#include "static_assert.h"
37#include "type_traits.h"
38
39namespace etl
40{
41 template <typename T>
43 {
44 typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type type;
45 };
46
47 //*****************************************************************************
59 //*****************************************************************************
60
61 //***************************************************************************
65 //***************************************************************************
66 template <uint32_t Scaling, typename T>
67 ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
68 {
69 typedef typename scaled_rounding_t<T>::type scale_t;
70
71 if (Scaling == 1)
72 {
73 return value;
74 }
75
76 if (value >= 0)
77 {
78 return T((value + scale_t(Scaling - 1U)) / scale_t(Scaling));
79 }
80 else
81 {
82 return T(value / scale_t(Scaling));
83 }
84 }
85
86 //***************************************************************************
90 //***************************************************************************
91 template <uint32_t Scaling, typename T>
92 ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_scaled(T value) ETL_NOEXCEPT
93 {
94 typedef typename scaled_rounding_t<T>::type scale_t;
95
96 return round_ceiling_unscaled<Scaling>(value) * scale_t(Scaling);
97 }
98
99 //***************************************************************************
103 //***************************************************************************
104 template <uint32_t Scaling, typename T>
105 ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_unscaled(T value) ETL_NOEXCEPT
106 {
107 typedef typename scaled_rounding_t<T>::type scale_t;
108 if (Scaling == 1)
109 {
110 return value;
111 }
112
113 if (value >= 0)
114 {
115 return T(value / scale_t(Scaling));
116 }
117 else
118 {
119 return T((value - scale_t(Scaling - 1)) / scale_t(Scaling));
120 }
121 }
122
123 //***************************************************************************
127 //***************************************************************************
128 template <uint32_t Scaling, typename T>
129 ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_scaled(T value) ETL_NOEXCEPT
130 {
131 typedef typename scaled_rounding_t<T>::type scale_t;
132
133 return T(round_floor_unscaled<Scaling>(value) * scale_t(Scaling));
134 }
135
136 //***************************************************************************
141 //***************************************************************************
142 template <uint32_t Scaling, typename T>
143 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_unscaled(T value) ETL_NOEXCEPT
144 {
145 typedef typename scaled_rounding_t<T>::type scale_t;
146
147 if (Scaling == 1)
148 {
149 return value;
150 }
151 else
152 {
153 if (value >= 0)
154 {
155 return T((value + scale_t(Scaling / 2U)) / scale_t(Scaling));
156 }
157 else
158 {
159 return T((value - scale_t(Scaling / 2U)) / scale_t(Scaling));
160 }
161 }
162 }
163
164 //***************************************************************************
169 //***************************************************************************
170 template <uint32_t Scaling, typename T>
171 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_scaled(T value) ETL_NOEXCEPT
172 {
173 typedef typename scaled_rounding_t<T>::type scale_t;
174
175 return T(round_half_up_unscaled<Scaling>(value) * scale_t(Scaling));
176 }
177
178 //***************************************************************************
183 //***************************************************************************
184 template <uint32_t Scaling, typename T>
185 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_unscaled(T value) ETL_NOEXCEPT
186 {
187 typedef typename scaled_rounding_t<T>::type scale_t;
188
189 if (Scaling == 1)
190 {
191 return value;
192 }
193
194 if (value >= 0)
195 {
196 return T((value + scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
197 }
198 else
199 {
200 return T((value - scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
201 }
202 }
203
204 //***************************************************************************
209 //***************************************************************************
210 template <uint32_t Scaling, typename T>
211 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_scaled(T value) ETL_NOEXCEPT
212 {
213 typedef typename scaled_rounding_t<T>::type scale_t;
214
215 return T(round_half_down_unscaled<Scaling>(value) * scale_t(Scaling));
216 }
217
218 //***************************************************************************
222 //***************************************************************************
223 template <uint32_t Scaling, typename T>
224 ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_unscaled(T value) ETL_NOEXCEPT
225 {
226 typedef typename scaled_rounding_t<T>::type scale_t;
227
228 if (Scaling == 1)
229 {
230 return value;
231 }
232 else
233 {
234 return T(value / scale_t(Scaling));
235 }
236 }
237
238 //***************************************************************************
242 //***************************************************************************
243 template <uint32_t Scaling, typename T>
244 ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_scaled(T value) ETL_NOEXCEPT
245 {
246 typedef typename scaled_rounding_t<T>::type scale_t;
247
248 return T(round_zero_unscaled<Scaling>(value) * scale_t(Scaling));
249 }
250
251 //***************************************************************************
255 //***************************************************************************
256 template <uint32_t Scaling, typename T>
257 ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_unscaled(T value) ETL_NOEXCEPT
258 {
259 if (value >= 0)
260 {
262 }
263 else
264 {
266 }
267 }
268
269 //***************************************************************************
273 //***************************************************************************
274 template <uint32_t Scaling, typename T>
275 ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_scaled(T value) ETL_NOEXCEPT
276 {
277 typedef typename scaled_rounding_t<T>::type scale_t;
278
279 return T(round_infinity_unscaled<Scaling>(value) * scale_t(Scaling));
280 }
281
282 //***************************************************************************
287 //***************************************************************************
288 template <uint32_t Scaling, typename T>
289 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
290 {
291 typedef typename scaled_rounding_t<T>::type scale_t;
292
293 if (Scaling == 1)
294 {
295 return value;
296 }
297 else
298 {
299 // Half?
300 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
301 {
302 // Odd?
303 if (static_cast<unsigned int>(value / scale_t(Scaling)) & 1U)
304 {
305 return T(round_half_up_unscaled<Scaling>(value));
306 }
307 else
308 {
309 return T(round_half_down_unscaled<Scaling>(value));
310 }
311 }
312 else
313 {
314 return T(round_half_up_unscaled<Scaling>(value));
315 }
316 }
317 }
318
319 //***************************************************************************
324 //***************************************************************************
325 template <uint32_t Scaling, typename T>
326 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_scaled(T value) ETL_NOEXCEPT
327 {
328 typedef typename scaled_rounding_t<T>::type scale_t;
329
330 return T(round_half_even_unscaled<Scaling>(value) * scale_t(Scaling));
331 }
332
333 //***************************************************************************
338 //***************************************************************************
339 template <uint32_t Scaling, typename T>
340 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
341 {
342 typedef typename scaled_rounding_t<T>::type scale_t;
343
344 if (Scaling == 1)
345 {
346 return value;
347 }
348 else
349 {
350 // Half?
351 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
352 {
353 // Odd?
354 if (static_cast<unsigned int>(value / scale_t(Scaling)) & 1U)
355 {
356 return T(round_half_down_unscaled<Scaling>(value));
357 }
358 else
359 {
360 return T(round_half_up_unscaled<Scaling>(value));
361 }
362 }
363 else
364 {
365 return T(round_half_up_unscaled<Scaling>(value));
366 }
367 }
368 }
369
370 //***************************************************************************
375 //***************************************************************************
376 template <uint32_t Scaling, typename T>
377 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_scaled(T value) ETL_NOEXCEPT
378 {
379 typedef typename scaled_rounding_t<T>::type scale_t;
380
381 return T(round_half_odd_unscaled<Scaling>(value) * scale_t(Scaling));
382 }
383} // namespace etl
384
385#endif
bitset_ext
Definition absolute.h:40
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:257
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:340
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:129
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:211
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:185
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:326
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:275
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:105
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:224
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:244
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:143
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:92
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:171
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:289
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:67
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:377
Definition scaled_rounding.h:43