diff options
Diffstat (limited to 'base')
-rw-r--r-- | base/base_tests/math_test.cpp | 22 | ||||
-rw-r--r-- | base/exception.hpp | 2 | ||||
-rw-r--r-- | base/math.hpp | 61 |
3 files changed, 41 insertions, 44 deletions
diff --git a/base/base_tests/math_test.cpp b/base/base_tests/math_test.cpp index 16eb1e5f9c..cc79055856 100644 --- a/base/base_tests/math_test.cpp +++ b/base/base_tests/math_test.cpp @@ -158,3 +158,25 @@ UNIT_TEST(GCD_Test) TEST_EQUAL(my::GCD(8, 3), 1, ()); TEST_EQUAL(my::GCD(9, 3), 3, ()); } + +UNIT_TEST(LCM_Test) +{ + TEST_EQUAL(my::LCM(6, 3), 6, ()); + TEST_EQUAL(my::LCM(14, 7), 14, ()); + TEST_EQUAL(my::LCM(100, 100), 100, ()); + TEST_EQUAL(my::LCM(7, 3), 21, ()); + TEST_EQUAL(my::LCM(8, 3), 24, ()); + TEST_EQUAL(my::LCM(9, 3), 9, ()); +} + +UNIT_TEST(Sign_test) +{ + TEST_EQUAL(1, my::Sign(1), ()); + TEST_EQUAL(1, my::Sign(10.4), ()); + + TEST_EQUAL(0, my::Sign(0), ()); + TEST_EQUAL(0, my::Sign(0.0), ()); + + TEST_EQUAL(-1, my::Sign(-11), ()); + TEST_EQUAL(-1, my::Sign(-10.4), ()); +} diff --git a/base/exception.hpp b/base/exception.hpp index 87be96775e..41b614e236 100644 --- a/base/exception.hpp +++ b/base/exception.hpp @@ -32,7 +32,7 @@ private: class exception_name : public base_exception \ { \ public: \ - exception_name(char const * what, string const & msg) : base_exception(what, msg) {} \ + exception_name(char const * what, std::string const & msg) : base_exception(what, msg) {} \ } // TODO: Use SRC_LOGGING macro. diff --git a/base/math.hpp b/base/math.hpp index 396be414ea..c54f74843c 100644 --- a/base/math.hpp +++ b/base/math.hpp @@ -180,50 +180,17 @@ inline uint32_t NextPowOf2(uint32_t v) return v + 1; } +template <typename Number, + typename EnableIf = typename std::enable_if< + std::is_integral<Number>::value, void>::type> // Greatest Common Divisor -template <typename T> T GCD(T a, T b) -{ - T multiplier = 1; - T gcd = 1; - while (true) - { - if (a == 0 || b == 0) - { - gcd = std::max(a, b); - break; - } - - if (a == 1 || b == 1) - { - gcd = 1; - break; - } - - if ((a & 0x1) == 0 && (b & 0x1) == 0) - { - multiplier <<= 1; - a >>= 1; - b >>= 1; - continue; - } - - if ((a & 0x1) != 0 && (b & 0x1) != 0) - { - T const minV = std::min(a, b); - T const maxV = std::max(a, b); - a = (maxV - minV) >> 1; - b = minV; - continue; - } - - if ((a & 0x1) != 0) - std::swap(a, b); - - a >>= 1; - } - - return multiplier * gcd; -} +Number constexpr GCD(Number const a, Number const b) { return b == 0 ? a : GCD(b, a % b); } + +template <typename Number, + typename EnableIf = typename std::enable_if< + std::is_integral<Number>::value, void>::type> +// Lowest Common Multiple. +Number constexpr LCM(Number const a, Number const b) { return a / GCD(a, b) * b; } /// Calculate hash for the pair of values. template <typename T1, typename T2> @@ -233,4 +200,12 @@ size_t Hash(T1 const & t1, T2 const & t2) return (std::hash<T1>()(t1) ^ (std::hash<T2>()(t2) << 1)); } +template <typename Number, + typename EnableIf = typename std::enable_if< + std::is_integral<Number>::value || std::is_floating_point<Number>::value, + void>::type> +int constexpr Sign(Number const number) noexcept +{ + return number == 0 ? 0 : number > 0 ? 1 : -1; +} } |