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