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 {
44 };
45
46 //*****************************************************************************
59 //*****************************************************************************
60
61 //***************************************************************************
65 //***************************************************************************
66 template <uint32_t SCALING, typename T>
68 {
69 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
70 typedef typename scaled_rounding_t<T>::type scale_t;
71
72 if (value >= 0)
73 {
74 return T((value + scale_t(SCALING)) / scale_t(SCALING));
75 }
76 else
77 {
78 return T(value / scale_t(SCALING));
79 }
80 }
81
82 //***************************************************************************
86 //***************************************************************************
87 template <uint32_t SCALING, typename T>
89 {
90 typedef typename scaled_rounding_t<T>::type scale_t;
91
92 return round_ceiling_unscaled<SCALING>(value) * scale_t(SCALING);
93 }
94
95 //***************************************************************************
99 //***************************************************************************
100 template <uint32_t SCALING, typename T>
102 {
103 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
104 typedef typename scaled_rounding_t<T>::type scale_t;
105
106 if (value >= 0)
107 {
108 return T(value / scale_t(SCALING));
109 }
110 else
111 {
112 return T((value - scale_t(SCALING)) / scale_t(SCALING));
113 }
114 }
115
116 //***************************************************************************
120 //***************************************************************************
121 template <uint32_t SCALING, typename T>
123 {
124 typedef typename scaled_rounding_t<T>::type scale_t;
125
126 return T(round_floor_unscaled<SCALING>(value) * scale_t(SCALING));
127 }
128
129 //***************************************************************************
134 //***************************************************************************
135 template <uint32_t SCALING, typename T>
137 {
138 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
139 ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
140 typedef typename scaled_rounding_t<T>::type scale_t;
141
142 if (value >= 0)
143 {
144 return T((value + scale_t(SCALING / 2U)) / scale_t(SCALING));
145 }
146 else
147 {
148 return T((value - scale_t(SCALING / 2U)) / scale_t(SCALING));
149 }
150 }
151
152 //***************************************************************************
157 //***************************************************************************
158 template <uint32_t SCALING, typename T>
160 {
161 typedef typename scaled_rounding_t<T>::type scale_t;
162
163 return T(round_half_up_unscaled<SCALING>(value) * scale_t(SCALING));
164 }
165
166 //***************************************************************************
171 //***************************************************************************
172 template <uint32_t SCALING, typename T>
174 {
175 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
176 ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
177 typedef typename scaled_rounding_t<T>::type scale_t;
178
179 if (value >= 0)
180 {
181 return T((value + scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
182 }
183 else
184 {
185 return T((value - scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
186 }
187 }
188
189 //***************************************************************************
194 //***************************************************************************
195 template <uint32_t SCALING, typename T>
197 {
198 typedef typename scaled_rounding_t<T>::type scale_t;
199
200 return T(round_half_down_unscaled<SCALING>(value) * scale_t(SCALING));
201 }
202
203 //***************************************************************************
207 //***************************************************************************
208 template <uint32_t SCALING, typename T>
210 {
211 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
212 typedef typename scaled_rounding_t<T>::type scale_t;
213
214 return T(value / scale_t(SCALING));
215 }
216
217 //***************************************************************************
221 //***************************************************************************
222 template <uint32_t SCALING, typename T>
224 {
225 typedef typename scaled_rounding_t<T>::type scale_t;
226
227 return T(round_zero_unscaled<SCALING>(value) * scale_t(SCALING));
228 }
229
230 //***************************************************************************
234 //***************************************************************************
235 template <uint32_t SCALING, typename T>
237 {
238 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
239 typedef typename scaled_rounding_t<T>::type scale_t;
240
241 if (value >= 0)
242 {
243 return T((value + scale_t(SCALING)) / scale_t(SCALING));
244 }
245 else
246 {
247 return T((value - scale_t(SCALING)) / scale_t(SCALING));
248 }
249 }
250
251 //***************************************************************************
255 //***************************************************************************
256 template <uint32_t SCALING, typename T>
258 {
259 typedef typename scaled_rounding_t<T>::type scale_t;
260
261 return T(round_infinity_unscaled<SCALING>(value) * scale_t(SCALING));
262 }
263
264 //***************************************************************************
269 //***************************************************************************
270 template <uint32_t SCALING, typename T>
272 {
273 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
274 typedef typename scaled_rounding_t<T>::type scale_t;
275
276 // Half?
277 if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
278 {
279 // Odd?
280 if ((value / scale_t(SCALING)) & 1U)
281 {
282 return T(round_half_up_unscaled<SCALING>(value));
283 }
284 else
285 {
287 }
288 }
289 else
290 {
291 return T(round_half_up_unscaled<SCALING>(value));
292 }
293 }
294
295 //***************************************************************************
300 //***************************************************************************
301 template <uint32_t SCALING, typename T>
303 {
304 typedef typename scaled_rounding_t<T>::type scale_t;
305
306 return T(round_half_even_unscaled<SCALING>(value) * scale_t(SCALING));
307 }
308
309 //***************************************************************************
314 //***************************************************************************
315 template <uint32_t SCALING, typename T>
317 {
318 ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
319 typedef typename scaled_rounding_t<T>::type scale_t;
320
321 // Half?
322 if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
323 {
324 // Odd?
325 if ((value / scale_t(SCALING)) & 1U)
326 {
328 }
329 else
330 {
331 return T(round_half_up_unscaled<SCALING>(value));
332 }
333 }
334 else
335 {
336 return T(round_half_up_unscaled<SCALING>(value));
337 }
338 }
339
340 //***************************************************************************
345 //***************************************************************************
346 template <uint32_t SCALING, typename T>
348 {
349 typedef typename scaled_rounding_t<T>::type scale_t;
350
351 return T(round_half_odd_unscaled<SCALING>(value) * scale_t(SCALING));
352 }
353}
354
355#endif
is_integral
Definition type_traits_generator.h:1001
bitset_ext
Definition absolute.h:38
T round_half_even_unscaled(T value)
Definition scaled_rounding.h:271
T round_ceiling_scaled(T value)
Definition scaled_rounding.h:88
T round_infinity_unscaled(T value)
Definition scaled_rounding.h:236
T round_half_down_scaled(T value)
Definition scaled_rounding.h:196
T round_half_even_scaled(T value)
Definition scaled_rounding.h:302
T round_half_odd_scaled(T value)
Definition scaled_rounding.h:347
T round_half_up_scaled(T value)
Definition scaled_rounding.h:159
T round_infinity_scaled(T value)
Definition scaled_rounding.h:257
T round_floor_scaled(T value)
Definition scaled_rounding.h:122
T round_zero_unscaled(T value)
Definition scaled_rounding.h:209
T round_ceiling_unscaled(T value)
Definition scaled_rounding.h:67
T round_half_up_unscaled(T value)
Definition scaled_rounding.h:136
T round_floor_unscaled(T value)
Definition scaled_rounding.h:101
T round_half_odd_unscaled(T value)
Definition scaled_rounding.h:316
T round_zero_scaled(T value)
Definition scaled_rounding.h:223
T round_half_down_unscaled(T value)
Definition scaled_rounding.h:173
pair holds two objects of arbitrary type
Definition utility.h:164
Definition scaled_rounding.h:42