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