1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Utility.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 35584 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_MATH_UTILITY_H_
17 #define NN_MATH_MATH_UTILITY_H_
18 
19 #include <nn/types.h>
20 
21 namespace nn { namespace math {
22 
23 /*!
24     @name    数学関数
25     @{
26 */
27 
28     /*!
29         @brief 絶対値を求めます。
30 
31         @tparam     T   数値を表わす型
32         @param[in]  x   絶対値を求めたい値
33         @return     x の絶対値を返します。
34     */
35     template <typename T>
Abs(T x)36     inline T Abs(T x)
37     {
38         return (x >= 0) ? x: -x;
39     }
40 
41     /*!
42         :overload   different_type
43         @brief 最大値を求めます。
44 
45         @tparam     T   数値を表わす型
46         @tparam     U   数値を表わす型
47         @tparam     S   返り値の型
48         @param[in]  a   引数 b と比較させる値
49         @param[in]  b   引数 a と比較させる値
50         @return     a と b を比較し、大きい方の値を返します。
51     */
52     template <typename T, typename U, typename S>
Max(T a,U b)53     inline S Max(T a, U b)
54     {
55         return (a >= b) ? a: b;
56     }
57 
58     /*!
59         :overload   same_type
60         @brief 最大値を求めます。
61 
62         @tparam     T   数値を表わす型
63         @param[in]  a   引数 b と比較させる値
64         @param[in]  b   引数 a と比較させる値
65         @return     a と b を比較し、大きい方の値を返します。
66     */
67     template <typename T>
Max(T a,T b)68     inline T Max(T a, T b)
69     {
70         return (a >= b) ? a: b;
71     }
72 
73     /*!
74         :overload   different_type
75         @brief 最小値を求めます。
76 
77         @tparam     T   数値を表わす型
78         @tparam     U   数値を表わす型
79         @tparam     S   返り値の型
80         @param[in]  a   引数 b と比較させる値
81         @param[in]  b   引数 a と比較させる値
82         @return     a と b を比較し、小さい方の値を返します。
83     */
84     template <typename T, typename U, typename S>
Min(T a,U b)85     inline S Min(T a, U b)
86     {
87         return (a <= b) ? a: b;
88     }
89 
90     /*!
91         :overload   same_type
92         @brief 最小値を求めます。
93 
94         @tparam     T   数値を表わす型
95         @param[in]  a   引数 b と比較させる値
96         @param[in]  b   引数 a と比較させる値
97         @return     a と b を比較し、小さい方の値を返します。
98     */
99     template <typename T>
Min(T a,T b)100     inline T Min(T a, T b)
101     {
102         return (a <= b) ? a: b;
103     }
104 
105     /*!
106         :overload   three_different_type
107         @brief 最大値を求めます。
108 
109         @tparam     T   数値を表わす型
110         @tparam     U   数値を表わす型
111         @tparam     R   数値を表わす型
112         @tparam     S   返り値の型
113         @param[in]  a   他の引数と比較させる値
114         @param[in]  b   他の引数と比較させる値
115         @param[in]  c   他の引数と比較させる値
116         @return     a, b, c を比較し、最も大きい値を返します。
117     */
118     template <typename T, typename U, typename R, typename S>
Max(T a,U b,R c)119     inline S Max(T a, U b, R c)
120     {
121         return (a >= b) ? ((a >= c) ? a: c) : ((b >= c) ? b: c);
122     }
123 
124     /*!
125         :overload   three_same_type
126         @brief 最大値を求めます。
127 
128         @tparam     T   数値を表わす型
129         @param[in]  a   他の引数と比較させる値
130         @param[in]  b   他の引数と比較させる値
131         @param[in]  c   他の引数と比較させる値
132         @return     a, b, c を比較し、最も大きい値を返します。
133     */
134     template <typename T>
Max(T a,T b,T c)135     inline T Max(T a, T b, T c)
136     {
137         return (a >= b) ? ((a >= c) ? a: c) : ((b >= c) ? b: c);
138     }
139 
140     /*!
141         :overload   three_different_type
142         @brief 最小値を求めます。
143 
144         @tparam     T   数値を表わす型
145         @tparam     U   数値を表わす型
146         @tparam     R   数値を表わす型
147         @tparam     S   返り値の型
148         @param[in]  a   他の引数と比較させる値
149         @param[in]  b   他の引数と比較させる値
150         @param[in]  c   他の引数と比較させる値
151         @return     a, b, c を比較し、最も小さい値を返します。
152     */
153     template <typename T, typename U, typename R, typename S>
Min(T a,U b,R c)154     inline S Min(T a, U b, R c)
155     {
156         return (a <= b) ? ((a <= c) ? a: c) : ((b <= c) ? b: c);
157     }
158 
159     /*!
160         :overload   three_same_type
161         @brief 最大値を求めます。
162 
163         @tparam     T   数値を表わす型
164         @param[in]  a   他の引数と比較させる値
165         @param[in]  b   他の引数と比較させる値
166         @param[in]  c   他の引数と比較させる値
167         @return     a, b, c を比較し、最も小さい値を返します。
168     */
169     template <typename T>
Min(T a,T b,T c)170     inline T Min(T a, T b, T c)
171     {
172         return (a <= b) ? ((a <= c) ? a: c) : ((b <= c) ? b: c);
173     }
174 
175     /*!
176         @brief 値を指定した範囲に納めます。
177 
178         x が low と high の間でなければ、low と high のうち近い方の値を返します。
179 
180         @tparam     T       数値を表わす型
181         @param[in]  x       対象の値
182         @param[in]  low     小さい方の閾値
183         @param[in]  high    大きい方の閾値
184         @return     x が [low, high] ならば x をそのまま、範囲外ならば low または high のいずれかを返します。
185     */
186     template <typename T>
Clamp(T x,T low,T high)187     inline T Clamp(T x, T low, T high)
188     {
189         return (x >= high) ? high : ((x <= low) ? low: x);
190     }
191 
192     /*!
193         :overload   value
194         @brief 値を指定した値の倍数になるように切り上げます。
195 
196         @tparam        T       数値を表わす型
197         @param[in]     x       対象の値
198         @param[in]     base    基準値
199         @return     x 以上である base の倍数のうち最小値を返します。
200     */
201     template <typename T>
RoundUp(T x,u32 base)202     inline T RoundUp(T x, u32 base)
203     {
204         return static_cast<T>( (x + (base - 1)) & ~(base - 1) );
205     }
206 
207     /*!
208         :overload   pointer
209         @brief 値を指定した値の倍数になるように切り上げます。
210 
211         @param[in]     x       対象の値
212         @param[in]     base    基準値
213         @return     x 以上である base の倍数のうち最小値を返します。
214     */
215     template <>
RoundUp(void * x,u32 base)216     inline void* RoundUp(void* x, u32 base)
217     {
218         return reinterpret_cast<void*>( RoundUp(reinterpret_cast<uptr>(x), base) );
219     }
220 
221     /*!
222         :overload   const_pointer
223         @brief 値を指定した値の倍数になるように切り上げます。
224 
225         @param[in]     x       対象の値
226         @param[in]     base    基準値
227         @return     x 以上である base の倍数のうち最小値を返します。
228     */
229     template <>
RoundUp(const void * x,u32 base)230     inline const void* RoundUp(const void* x, u32 base)
231     {
232         return reinterpret_cast<const void*>( RoundUp(reinterpret_cast<uptr>(x), base) );
233     }
234 
235     /*!
236         :overload   value
237         @brief 値を指定した値の倍数になるように切り下げます。
238 
239         @tparam         T       数値を表わす型
240         @param[in]      x       対象の値
241         @param[in]      base    基準値
242         @return     x 以下である base の倍数のうち最大値を返します。
243     */
244     template <typename T>
RoundDown(T x,u32 base)245     inline T RoundDown(T x, u32 base)
246     {
247         return static_cast<T>( x & ~(base - 1) );
248     }
249 
250     /*!
251         :overload   pointer
252         @brief 値を指定した値の倍数になるように切り下げます。
253 
254         @param[in]     x       対象の値
255         @param[in]     base    基準値
256         @return     x 以下である base の倍数のうち最大値を返します。
257     */
258     template <>
RoundDown(void * x,u32 base)259     inline void* RoundDown(void* x, u32 base)
260     {
261         return reinterpret_cast<void*>( RoundDown(reinterpret_cast<uptr>(x), base) );
262     }
263 
264     /*!
265         :overload   const_pointer
266         @brief 値を指定した値の倍数になるように切り下げます。
267 
268         @param[in]     x       対象の値
269         @param[in]     base    基準値
270         @return     x 以下である base の倍数のうち最大値を返します。
271     */
272     template <>
RoundDown(const void * x,u32 base)273     inline const void* RoundDown(const void* x, u32 base)
274     {
275         return reinterpret_cast<const void*>( RoundDown(reinterpret_cast<uptr>(x), base) );
276     }
277 
278     /*!
279         @brief 2値の割り算で求めた商を求めます。余りがあれば切り上げます。
280 
281         @tparam     T       数値を表わす型
282         @param[in]  x       y で割られる値
283         @param[in]  y       x を割る値
284         @return     x を y で割り、余りを切り上げた値を返します。
285     */
286     template <typename T>
DivUp(T x,T y)287     inline T DivUp(T x, T y)
288     {
289         return static_cast<T>( (x + (y - 1)) / y );
290     }
291 
292     /*!
293         :overload   bit32
294         @brief  指定した範囲のビット値を抽出します。
295 
296         @tparam        T       返り値の型
297         @param[in]     v       対象の値
298         @param[in]     pos     最下位ビットからの位置
299         @param[in]     len     抽出範囲
300         @return     v に対して指定範囲を抽出した値
301     */
302     template <typename T>
ExtractBits(bit32 v,int pos,int len)303     inline T ExtractBits(bit32 v, int pos, int len)
304     {
305         return static_cast<T>( v & (((1u << len) - 1) << pos) );
306     }
307 
308     /*!
309         :overload   bit64
310         @brief  指定した範囲のビット値を抽出します。
311 
312         @tparam        T       返り値の型
313         @param[in]     v       対象の値
314         @param[in]     pos     最下位ビットからの位置
315         @param[in]     len     抽出範囲
316         @return     v に対して指定範囲を抽出した値
317     */
318     template <typename T>
ExtractBits(bit64 v,int pos,int len)319     inline T ExtractBits(bit64 v, int pos, int len)
320     {
321         return static_cast<T>( v & (((1ull << len) - 1) << pos) );
322     }
323 
324     /*!
325         :overload   bit32
326         @brief  指定した範囲のビット値を取得します。
327 
328         pos で指定した位置から長さ len の範囲を取得します。
329 
330         @tparam        T       返り値の型
331         @param[in]     v       対象の値
332         @param[in]     pos     最下位ビットからの位置
333         @param[in]     len     抽出範囲
334         @return     v から抽出した値
335     */
336     template <typename T>
GetBits(bit32 v,int pos,int len)337     inline T GetBits(bit32 v, int pos, int len)
338     {
339         return static_cast<T>( (v >> pos) & ((1u << len) - 1) );
340     }
341 
342     /*!
343         :overload   bit64
344         @brief  指定した範囲のビット値を取得します。
345 
346         pos で指定した位置から長さ len の範囲を取得します。
347 
348         @tparam        T       返り値の型
349         @param[in]     v       対象の値
350         @param[in]     pos     抽出する最下位ビットからの位置
351         @param[in]     len     抽出範囲
352         @return     v から抽出した値
353     */
354     template <typename T>
GetBits(bit64 v,int pos,int len)355     inline T GetBits(bit64 v, int pos, int len)
356     {
357         return static_cast<T>( (v >> pos) & ((1ull << len) - 1) );
358     }
359 
360     /*!
361         @brief  指定範囲のみを残した32ビットのデータを返します。
362 
363         v に対して 最下位ビットから shift ビット 移動した位置より width で指定した範囲を抽出します。
364 
365         @tparam        T         ビット列データを表わす型
366         @param[in]     v         対象の値
367         @param[in]     width     抽出する範囲
368         @param[in]     shift     最下位ビットからの位置
369         @return     v と width, shift から求めた結果を返します。
370     */
371     template <typename T>
MakeBits(T v,int width,int shift)372     inline bit32 MakeBits(T v, int width, int shift)
373     {
374         return (static_cast<bit32>(v) & ((1u << width) - 1)) << shift;
375     }
376 
377 /*!
378     @}
379 */
380 }}
381 
382 
383 #endif  // ifndef NN_MATH_MATH_UTILITY_H_
384