/*---------------------------------------------------------------------------* Project: Horizon File: math_Utility.h Copyright (C)2009-2010 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 35584 $ *---------------------------------------------------------------------------*/ #ifndef NN_MATH_MATH_UTILITY_H_ #define NN_MATH_MATH_UTILITY_H_ #include namespace nn { namespace math { /*! @name 数学関数 @{ */ /*! @brief 絶対値を求めます。 @tparam T 数値を表わす型 @param[in] x 絶対値を求めたい値 @return x の絶対値を返します。 */ template inline T Abs(T x) { return (x >= 0) ? x: -x; } /*! :overload different_type @brief 最大値を求めます。 @tparam T 数値を表わす型 @tparam U 数値を表わす型 @tparam S 返り値の型 @param[in] a 引数 b と比較させる値 @param[in] b 引数 a と比較させる値 @return a と b を比較し、大きい方の値を返します。 */ template inline S Max(T a, U b) { return (a >= b) ? a: b; } /*! :overload same_type @brief 最大値を求めます。 @tparam T 数値を表わす型 @param[in] a 引数 b と比較させる値 @param[in] b 引数 a と比較させる値 @return a と b を比較し、大きい方の値を返します。 */ template inline T Max(T a, T b) { return (a >= b) ? a: b; } /*! :overload different_type @brief 最小値を求めます。 @tparam T 数値を表わす型 @tparam U 数値を表わす型 @tparam S 返り値の型 @param[in] a 引数 b と比較させる値 @param[in] b 引数 a と比較させる値 @return a と b を比較し、小さい方の値を返します。 */ template inline S Min(T a, U b) { return (a <= b) ? a: b; } /*! :overload same_type @brief 最小値を求めます。 @tparam T 数値を表わす型 @param[in] a 引数 b と比較させる値 @param[in] b 引数 a と比較させる値 @return a と b を比較し、小さい方の値を返します。 */ template inline T Min(T a, T b) { return (a <= b) ? a: b; } /*! :overload three_different_type @brief 最大値を求めます。 @tparam T 数値を表わす型 @tparam U 数値を表わす型 @tparam R 数値を表わす型 @tparam S 返り値の型 @param[in] a 他の引数と比較させる値 @param[in] b 他の引数と比較させる値 @param[in] c 他の引数と比較させる値 @return a, b, c を比較し、最も大きい値を返します。 */ template inline S Max(T a, U b, R c) { return (a >= b) ? ((a >= c) ? a: c) : ((b >= c) ? b: c); } /*! :overload three_same_type @brief 最大値を求めます。 @tparam T 数値を表わす型 @param[in] a 他の引数と比較させる値 @param[in] b 他の引数と比較させる値 @param[in] c 他の引数と比較させる値 @return a, b, c を比較し、最も大きい値を返します。 */ template inline T Max(T a, T b, T c) { return (a >= b) ? ((a >= c) ? a: c) : ((b >= c) ? b: c); } /*! :overload three_different_type @brief 最小値を求めます。 @tparam T 数値を表わす型 @tparam U 数値を表わす型 @tparam R 数値を表わす型 @tparam S 返り値の型 @param[in] a 他の引数と比較させる値 @param[in] b 他の引数と比較させる値 @param[in] c 他の引数と比較させる値 @return a, b, c を比較し、最も小さい値を返します。 */ template inline S Min(T a, U b, R c) { return (a <= b) ? ((a <= c) ? a: c) : ((b <= c) ? b: c); } /*! :overload three_same_type @brief 最大値を求めます。 @tparam T 数値を表わす型 @param[in] a 他の引数と比較させる値 @param[in] b 他の引数と比較させる値 @param[in] c 他の引数と比較させる値 @return a, b, c を比較し、最も小さい値を返します。 */ template inline T Min(T a, T b, T c) { return (a <= b) ? ((a <= c) ? a: c) : ((b <= c) ? b: c); } /*! @brief 値を指定した範囲に納めます。 x が low と high の間でなければ、low と high のうち近い方の値を返します。 @tparam T 数値を表わす型 @param[in] x 対象の値 @param[in] low 小さい方の閾値 @param[in] high 大きい方の閾値 @return x が [low, high] ならば x をそのまま、範囲外ならば low または high のいずれかを返します。 */ template inline T Clamp(T x, T low, T high) { return (x >= high) ? high : ((x <= low) ? low: x); } /*! :overload value @brief 値を指定した値の倍数になるように切り上げます。 @tparam T 数値を表わす型 @param[in] x 対象の値 @param[in] base 基準値 @return x 以上である base の倍数のうち最小値を返します。 */ template inline T RoundUp(T x, u32 base) { return static_cast( (x + (base - 1)) & ~(base - 1) ); } /*! :overload pointer @brief 値を指定した値の倍数になるように切り上げます。 @param[in] x 対象の値 @param[in] base 基準値 @return x 以上である base の倍数のうち最小値を返します。 */ template <> inline void* RoundUp(void* x, u32 base) { return reinterpret_cast( RoundUp(reinterpret_cast(x), base) ); } /*! :overload const_pointer @brief 値を指定した値の倍数になるように切り上げます。 @param[in] x 対象の値 @param[in] base 基準値 @return x 以上である base の倍数のうち最小値を返します。 */ template <> inline const void* RoundUp(const void* x, u32 base) { return reinterpret_cast( RoundUp(reinterpret_cast(x), base) ); } /*! :overload value @brief 値を指定した値の倍数になるように切り下げます。 @tparam T 数値を表わす型 @param[in] x 対象の値 @param[in] base 基準値 @return x 以下である base の倍数のうち最大値を返します。 */ template inline T RoundDown(T x, u32 base) { return static_cast( x & ~(base - 1) ); } /*! :overload pointer @brief 値を指定した値の倍数になるように切り下げます。 @param[in] x 対象の値 @param[in] base 基準値 @return x 以下である base の倍数のうち最大値を返します。 */ template <> inline void* RoundDown(void* x, u32 base) { return reinterpret_cast( RoundDown(reinterpret_cast(x), base) ); } /*! :overload const_pointer @brief 値を指定した値の倍数になるように切り下げます。 @param[in] x 対象の値 @param[in] base 基準値 @return x 以下である base の倍数のうち最大値を返します。 */ template <> inline const void* RoundDown(const void* x, u32 base) { return reinterpret_cast( RoundDown(reinterpret_cast(x), base) ); } /*! @brief 2値の割り算で求めた商を求めます。余りがあれば切り上げます。 @tparam T 数値を表わす型 @param[in] x y で割られる値 @param[in] y x を割る値 @return x を y で割り、余りを切り上げた値を返します。 */ template inline T DivUp(T x, T y) { return static_cast( (x + (y - 1)) / y ); } /*! :overload bit32 @brief 指定した範囲のビット値を抽出します。 @tparam T 返り値の型 @param[in] v 対象の値 @param[in] pos 最下位ビットからの位置 @param[in] len 抽出範囲 @return v に対して指定範囲を抽出した値 */ template inline T ExtractBits(bit32 v, int pos, int len) { return static_cast( v & (((1u << len) - 1) << pos) ); } /*! :overload bit64 @brief 指定した範囲のビット値を抽出します。 @tparam T 返り値の型 @param[in] v 対象の値 @param[in] pos 最下位ビットからの位置 @param[in] len 抽出範囲 @return v に対して指定範囲を抽出した値 */ template inline T ExtractBits(bit64 v, int pos, int len) { return static_cast( v & (((1ull << len) - 1) << pos) ); } /*! :overload bit32 @brief 指定した範囲のビット値を取得します。 pos で指定した位置から長さ len の範囲を取得します。 @tparam T 返り値の型 @param[in] v 対象の値 @param[in] pos 最下位ビットからの位置 @param[in] len 抽出範囲 @return v から抽出した値 */ template inline T GetBits(bit32 v, int pos, int len) { return static_cast( (v >> pos) & ((1u << len) - 1) ); } /*! :overload bit64 @brief 指定した範囲のビット値を取得します。 pos で指定した位置から長さ len の範囲を取得します。 @tparam T 返り値の型 @param[in] v 対象の値 @param[in] pos 抽出する最下位ビットからの位置 @param[in] len 抽出範囲 @return v から抽出した値 */ template inline T GetBits(bit64 v, int pos, int len) { return static_cast( (v >> pos) & ((1ull << len) - 1) ); } /*! @brief 指定範囲のみを残した32ビットのデータを返します。 v に対して 最下位ビットから shift ビット 移動した位置より width で指定した範囲を抽出します。 @tparam T ビット列データを表わす型 @param[in] v 対象の値 @param[in] width 抽出する範囲 @param[in] shift 最下位ビットからの位置 @return v と width, shift から求めた結果を返します。 */ template inline bit32 MakeBits(T v, int width, int shift) { return (static_cast(v) & ((1u << width) - 1)) << shift; } /*! @} */ }} #endif // ifndef NN_MATH_MATH_UTILITY_H_