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 "type_traits.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 ETL_CONSTEXPR14 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
67 {
68 typedef typename scaled_rounding_t<T>::type scale_t;
69
70 if (Scaling == 1)
71 {
72 return value;
73 }
74
75 if (value >= 0)
76 {
77 return T((value + scale_t(Scaling - 1U)) / scale_t(Scaling));
78 }
79 else
80 {
81 return T(value / scale_t(Scaling));
82 }
83 }
84
85 //***************************************************************************
89 //***************************************************************************
90 template <uint32_t Scaling, typename T>
91 ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_scaled(T value) ETL_NOEXCEPT
92 {
93 typedef typename scaled_rounding_t<T>::type scale_t;
94
95 return round_ceiling_unscaled<Scaling>(value) * scale_t(Scaling);
96 }
97
98 //***************************************************************************
102 //***************************************************************************
103 template <uint32_t Scaling, typename T>
104 ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_unscaled(T value) ETL_NOEXCEPT
105 {
106 typedef typename scaled_rounding_t<T>::type scale_t;
107 if (Scaling == 1)
108 {
109 return value;
110 }
111
112 if (value >= 0)
113 {
114 return T(value / scale_t(Scaling));
115 }
116 else
117 {
118 return T((value - scale_t(Scaling - 1)) / scale_t(Scaling));
119 }
120 }
121
122 //***************************************************************************
126 //***************************************************************************
127 template <uint32_t Scaling, typename T>
128 ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_scaled(T value) ETL_NOEXCEPT
129 {
130 typedef typename scaled_rounding_t<T>::type scale_t;
131
132 return T(round_floor_unscaled<Scaling>(value) * scale_t(Scaling));
133 }
134
135 //***************************************************************************
140 //***************************************************************************
141 template <uint32_t Scaling, typename T>
142 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_unscaled(T value) ETL_NOEXCEPT
143 {
144 typedef typename scaled_rounding_t<T>::type scale_t;
145
146 if (Scaling == 1)
147 {
148 return value;
149 }
150 else
151 {
152 if (value >= 0)
153 {
154 return T((value + scale_t(Scaling / 2U)) / scale_t(Scaling));
155 }
156 else
157 {
158 return T((value - scale_t(Scaling / 2U)) / scale_t(Scaling));
159 }
160 }
161 }
162
163 //***************************************************************************
168 //***************************************************************************
169 template <uint32_t Scaling, typename T>
170 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_scaled(T value) ETL_NOEXCEPT
171 {
172 typedef typename scaled_rounding_t<T>::type scale_t;
173
174 return T(round_half_up_unscaled<Scaling>(value) * scale_t(Scaling));
175 }
176
177 //***************************************************************************
182 //***************************************************************************
183 template <uint32_t Scaling, typename T>
184 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_unscaled(T value) ETL_NOEXCEPT
185 {
186 typedef typename scaled_rounding_t<T>::type scale_t;
187
188 if (Scaling == 1)
189 {
190 return value;
191 }
192
193 if (value >= 0)
194 {
195 return T((value + scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
196 }
197 else
198 {
199 return T((value - scale_t((Scaling - 1) / 2U)) / scale_t(Scaling));
200 }
201 }
202
203 //***************************************************************************
208 //***************************************************************************
209 template <uint32_t Scaling, typename T>
210 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_scaled(T value) ETL_NOEXCEPT
211 {
212 typedef typename scaled_rounding_t<T>::type scale_t;
213
214 return T(round_half_down_unscaled<Scaling>(value) * scale_t(Scaling));
215 }
216
217 //***************************************************************************
221 //***************************************************************************
222 template <uint32_t Scaling, typename T>
223 ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_unscaled(T value) ETL_NOEXCEPT
224 {
225 typedef typename scaled_rounding_t<T>::type scale_t;
226
227 if (Scaling == 1)
228 {
229 return value;
230 }
231 else
232 {
233 return T(value / scale_t(Scaling));
234 }
235 }
236
237 //***************************************************************************
241 //***************************************************************************
242 template <uint32_t Scaling, typename T>
243 ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_scaled(T value) ETL_NOEXCEPT
244 {
245 typedef typename scaled_rounding_t<T>::type scale_t;
246
247 return T(round_zero_unscaled<Scaling>(value) * scale_t(Scaling));
248 }
249
250 //***************************************************************************
254 //***************************************************************************
255 template <uint32_t Scaling, typename T>
256 ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_unscaled(T value) ETL_NOEXCEPT
257 {
258 if (value >= 0)
259 {
261 }
262 else
263 {
265 }
266 }
267
268 //***************************************************************************
272 //***************************************************************************
273 template <uint32_t Scaling, typename T>
274 ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_scaled(T value) ETL_NOEXCEPT
275 {
276 typedef typename scaled_rounding_t<T>::type scale_t;
277
278 return T(round_infinity_unscaled<Scaling>(value) * scale_t(Scaling));
279 }
280
281 //***************************************************************************
286 //***************************************************************************
287 template <uint32_t Scaling, typename T>
288 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
289 {
290 typedef typename scaled_rounding_t<T>::type scale_t;
291
292 if (Scaling == 1)
293 {
294 return value;
295 }
296 else
297 {
298 // Half?
299 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
300 {
301 // Odd?
302 if (static_cast<unsigned int>(value / scale_t(Scaling)) & 1U)
303 {
304 return T(round_half_up_unscaled<Scaling>(value));
305 }
306 else
307 {
308 return T(round_half_down_unscaled<Scaling>(value));
309 }
310 }
311 else
312 {
313 return T(round_half_up_unscaled<Scaling>(value));
314 }
315 }
316 }
317
318 //***************************************************************************
323 //***************************************************************************
324 template <uint32_t Scaling, typename T>
325 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_scaled(T value) ETL_NOEXCEPT
326 {
327 typedef typename scaled_rounding_t<T>::type scale_t;
328
329 return T(round_half_even_unscaled<Scaling>(value) * scale_t(Scaling));
330 }
331
332 //***************************************************************************
337 //***************************************************************************
338 template <uint32_t Scaling, typename T>
339 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
340 {
341 typedef typename scaled_rounding_t<T>::type scale_t;
342
343 if (Scaling == 1)
344 {
345 return value;
346 }
347 else
348 {
349 // Half?
350 if ((etl::absolute(value) % scale_t(Scaling)) == scale_t(Scaling / 2U))
351 {
352 // Odd?
353 if (static_cast<unsigned int>(value / scale_t(Scaling)) & 1U)
354 {
355 return T(round_half_down_unscaled<Scaling>(value));
356 }
357 else
358 {
359 return T(round_half_up_unscaled<Scaling>(value));
360 }
361 }
362 else
363 {
364 return T(round_half_up_unscaled<Scaling>(value));
365 }
366 }
367 }
368
369 //***************************************************************************
374 //***************************************************************************
375 template <uint32_t Scaling, typename T>
376 ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_scaled(T value) ETL_NOEXCEPT
377 {
378 typedef typename scaled_rounding_t<T>::type scale_t;
379
380 return T(round_half_odd_unscaled<Scaling>(value) * scale_t(Scaling));
381 }
382} // namespace etl
383
384#endif
Definition absolute.h:40
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:256
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:339
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:128
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:210
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_down_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:184
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:325
ETL_NODISCARD ETL_CONSTEXPR14 T round_infinity_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:274
ETL_NODISCARD ETL_CONSTEXPR14 T round_floor_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:104
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:223
ETL_NODISCARD ETL_CONSTEXPR14 T round_zero_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:243
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:142
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:91
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_up_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:170
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:288
ETL_NODISCARD ETL_CONSTEXPR14 T round_ceiling_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:66
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_odd_scaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:376
Definition scaled_rounding.h:42