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 "static_assert.h"
35#include "type_traits.h"
36#include "absolute.h"
37
38namespace etl
39{
40 template <typename T>
42 {
43 typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type type;
44 };
45
46 //*****************************************************************************
58 //*****************************************************************************
59
60 //***************************************************************************
64 //***************************************************************************
65 template <uint32_t Scaling, typename T>
66 ETL_NODISCARD
67 ETL_CONSTEXPR14
68 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
69 {
70 typedef typename scaled_rounding_t<T>::type scale_t;
71
72 if (Scaling == 1)
73 {
74 return value;
75 }
76
77 if (value >= 0)
78 {
79 return T((value + scale_t(Scaling - 1U)) / scale_t(Scaling));
80 }
81 else
82 {
83 return T(value / scale_t(Scaling));
84 }
85 }
86
87 //***************************************************************************
91 //***************************************************************************
92 template <uint32_t Scaling, typename T>
93 ETL_NODISCARD
94 ETL_CONSTEXPR14
95 T round_ceiling_scaled(T value) ETL_NOEXCEPT
96 {
97 typedef typename scaled_rounding_t<T>::type scale_t;
98
99 return round_ceiling_unscaled<Scaling>(value) * scale_t(Scaling);
100 }
101
102 //***************************************************************************
106 //***************************************************************************
107 template <uint32_t Scaling, typename T>
108 ETL_NODISCARD
109 ETL_CONSTEXPR14
110 T round_floor_unscaled(T value) ETL_NOEXCEPT
111 {
112 typedef typename scaled_rounding_t<T>::type scale_t;
113 if (Scaling == 1)
114 {
115 return value;
116 }
117
118 if (value >= 0)
119 {
120 return T(value / scale_t(Scaling));
121 }
122 else
123 {
124 return T((value - scale_t(Scaling - 1)) / scale_t(Scaling));
125 }
126 }
127
128 //***************************************************************************
132 //***************************************************************************
133 template <uint32_t Scaling, typename T>
134 ETL_NODISCARD
135 ETL_CONSTEXPR14
136 T round_floor_scaled(T value) ETL_NOEXCEPT
137 {
138 typedef typename scaled_rounding_t<T>::type scale_t;
139
140 return T(round_floor_unscaled<Scaling>(value) * scale_t(Scaling));
141 }
142
143 //***************************************************************************
148 //***************************************************************************
149 template <uint32_t Scaling, typename T>
150 ETL_NODISCARD
151 ETL_CONSTEXPR14
152 T round_half_up_unscaled(T value) ETL_NOEXCEPT
153 {
154 typedef typename scaled_rounding_t<T>::type scale_t;
155
156 if (Scaling == 1)
157 {
158 return value;
159 }
160 else
161 {
162 if (value >= 0)
163 {
164 return T((value + scale_t(Scaling / 2U)) / scale_t(Scaling));
165 }
166 else
167 {
168 return T((value - scale_t(Scaling / 2U)) / scale_t(Scaling));
169 }
170 }
171 }
172
173 //***************************************************************************
178 //***************************************************************************
179 template <uint32_t Scaling, typename T>
180 ETL_NODISCARD
181 ETL_CONSTEXPR14
182 T round_half_up_scaled(T value) ETL_NOEXCEPT
183 {
184 typedef typename scaled_rounding_t<T>::type scale_t;
185
186 return T(round_half_up_unscaled<Scaling>(value) * scale_t(Scaling));
187 }
188
189 //***************************************************************************
194 //***************************************************************************
195 template <uint32_t Scaling, typename T>
196 ETL_NODISCARD
197 ETL_CONSTEXPR14
198 T round_half_down_unscaled(T value) ETL_NOEXCEPT
199 {
200 typedef typename scaled_rounding_t<T>::type scale_t;
201
202 if (Scaling == 1)
203 {
204 return value;
205 }
206
207 if (value >= 0)
208 {
209 return T((value + scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
210 }
211 else
212 {
213 return T((value - scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
214 }
215 }
216
217 //***************************************************************************
222 //***************************************************************************
223 template <uint32_t Scaling, typename T>
224 ETL_NODISCARD
225 ETL_CONSTEXPR14
226 T round_half_down_scaled(T value) ETL_NOEXCEPT
227 {
228 typedef typename scaled_rounding_t<T>::type scale_t;
229
230 return T(round_half_down_unscaled<Scaling>(value) * scale_t(Scaling));
231 }
232
233 //***************************************************************************
237 //***************************************************************************
238 template <uint32_t Scaling, typename T>
239 ETL_NODISCARD
240 ETL_CONSTEXPR14
241 T round_zero_unscaled(T value) ETL_NOEXCEPT
242 {
243 typedef typename scaled_rounding_t<T>::type scale_t;
244
245 if (Scaling == 1)
246 {
247 return value;
248 }
249 else
250 {
251 return T(value / scale_t(Scaling));
252 }
253 }
254
255 //***************************************************************************
259 //***************************************************************************
260 template <uint32_t Scaling, typename T>
261 ETL_NODISCARD
262 ETL_CONSTEXPR14
263 T round_zero_scaled(T value) ETL_NOEXCEPT
264 {
265 typedef typename scaled_rounding_t<T>::type scale_t;
266
267 return T(round_zero_unscaled<Scaling>(value) * scale_t(Scaling));
268 }
269
270 //***************************************************************************
274 //***************************************************************************
275 template <uint32_t Scaling, typename T>
276 ETL_NODISCARD
277 ETL_CONSTEXPR14
278 T round_infinity_unscaled(T value) ETL_NOEXCEPT
279 {
280 if (value >= 0)
281 {
283 }
284 else
285 {
287 }
288 }
289
290 //***************************************************************************
294 //***************************************************************************
295 template <uint32_t Scaling, typename T>
296 ETL_NODISCARD
297 ETL_CONSTEXPR14
298 T round_infinity_scaled(T value) ETL_NOEXCEPT
299 {
300 typedef typename scaled_rounding_t<T>::type scale_t;
301
302 return T(round_infinity_unscaled<Scaling>(value) * scale_t(Scaling));
303 }
304
305 //***************************************************************************
310 //***************************************************************************
311 template <uint32_t Scaling, typename T>
312 ETL_NODISCARD
313 ETL_CONSTEXPR14
314 T round_half_even_unscaled(T value) ETL_NOEXCEPT
315 {
316 typedef typename scaled_rounding_t<T>::type scale_t;
317
318 if (Scaling == 1)
319 {
320 return value;
321 }
322 else
323 {
324 // Half?
325 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
326 {
327 // Odd?
328 if ((value / scale_t(Scaling)) & 1U)
329 {
330 return T(round_half_up_unscaled<Scaling>(value));
331 }
332 else
333 {
335 }
336 }
337 else
338 {
339 return T(round_half_up_unscaled<Scaling>(value));
340 }
341 }
342 }
343
344 //***************************************************************************
349 //***************************************************************************
350 template <uint32_t Scaling, typename T>
351 ETL_NODISCARD
352 ETL_CONSTEXPR14
353 T round_half_even_scaled(T value) ETL_NOEXCEPT
354 {
355 typedef typename scaled_rounding_t<T>::type scale_t;
356
357 return T(round_half_even_unscaled<Scaling>(value) * scale_t(Scaling));
358 }
359
360 //***************************************************************************
365 //***************************************************************************
366 template <uint32_t Scaling, typename T>
367 ETL_NODISCARD
368 ETL_CONSTEXPR14
369 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
370 {
371 typedef typename scaled_rounding_t<T>::type scale_t;
372
373 if (Scaling == 1)
374 {
375 return value;
376 }
377 else
378 {
379 // Half?
380 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
381 {
382 // Odd?
383 if ((value / scale_t(Scaling)) & 1U)
384 {
386 }
387 else
388 {
389 return T(round_half_up_unscaled<Scaling>(value));
390 }
391 }
392 else
393 {
394 return T(round_half_up_unscaled<Scaling>(value));
395 }
396 }
397 }
398
399 //***************************************************************************
404 //***************************************************************************
405 template <uint32_t Scaling, typename T>
406 ETL_NODISCARD
407 ETL_CONSTEXPR14
408 T round_half_odd_scaled(T value) ETL_NOEXCEPT
409 {
410 typedef typename scaled_rounding_t<T>::type scale_t;
411
412 return T(round_half_odd_unscaled<Scaling>(value) * scale_t(Scaling));
413 }
414}
415
416#endif
conditional
Definition type_traits_generator.h:1199
bitset_ext
Definition absolute.h:38
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:278
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:369
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:136
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:226
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:198
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:353
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:298
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:110
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:241
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:263
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:152
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:95
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:182
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:314
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:68
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:408
Definition scaled_rounding.h:42