feat: Add math_util::percentage_to_value

This commit is contained in:
Michael Carlberg 2016-10-25 07:04:14 +02:00
parent 7905f37462
commit bc67e64e79
3 changed files with 68 additions and 8 deletions

View File

@ -10,10 +10,10 @@ namespace math_util {
/** /**
* Limit value T by min and max bounds * Limit value T by min and max bounds
*/ */
template <typename T> template <typename ValueType>
T cap(T value, T min_value, T max_value) { ValueType cap(ValueType value, ValueType min_value, ValueType max_value) {
value = std::min<T>(value, max_value); value = std::min<ValueType>(value, max_value);
value = std::max<T>(value, min_value); value = std::max<ValueType>(value, min_value);
return value; return value;
} }
@ -21,10 +21,25 @@ namespace math_util {
* Calculate the percentage for a value * Calculate the percentage for a value
* within given range * within given range
*/ */
template <typename T> template <typename ValueType, typename ReturnType = int>
int percentage(T value, T min_value, T max_value) { ReturnType percentage(ValueType value, ValueType min_value, ValueType max_value) {
T percentage = ((value - min_value) / (max_value - min_value)) * 100.0f + 0.5f; auto upper = (max_value - min_value);
return cap<T>(std::ceil(percentage), 0, 100); auto lower = static_cast<float>(value - min_value);
ValueType percentage = (lower / upper) * 100.0f;
if (std::is_integral<ReturnType>())
percentage += 0.5f;
return cap<ReturnType>(percentage, 0.0f, 100.0f);
}
/**
* Get value for percentage of `max_value`
*/
template <typename ValueType, typename ReturnType = int>
ReturnType percentage_to_value(ValueType percentage, ValueType max_value) {
if (std::is_integral<ReturnType>())
return cap<ReturnType>(percentage * max_value / 100.0f + 0.5f, 0, max_value);
else
return cap<ReturnType>(percentage * max_value / 100.0f, 0.0f, max_value);
} }
} }

View File

@ -12,6 +12,7 @@ function(unit_test file)
add_test(unit_test.${testname} unit_test.${testname}) add_test(unit_test.${testname} unit_test.${testname})
endfunction() endfunction()
unit_test("utils/math")
unit_test("utils/memory") unit_test("utils/memory")
unit_test("utils/string") unit_test("utils/string")
unit_test("components/command_line") unit_test("components/command_line")

View File

@ -0,0 +1,44 @@
#include "utils/math.hpp"
int main() {
using namespace lemonbuddy;
"cap"_test = [] {
expect(math_util::cap<int>(8, 0, 10) == 8);
expect(math_util::cap<int>(-8, 0, 10) == 0);
expect(math_util::cap<int>(15, 0, 10) == 10);
expect(math_util::cap<float>(20.5f, 0.0f, 30.0f) == 20.5f);
expect(math_util::cap<float>(1.0f, 0.0f, 2.0f) == 1.0f);
expect(math_util::cap<float>(-2.0f, -5.0f, 5.0f) == -2.0f);
expect(math_util::cap<float>(1.0f, 0.0f, 0.0f) == 0);
};
"percentage"_test = [] {
expect(math_util::percentage<float, float>(5.5f, 0.0f, 10.0f) == 55.0f);
expect(math_util::percentage<float, int>(5.55f, 0.0f, 10.0f) == 56);
expect(math_util::percentage<float, float>(5.25f, 0.0f, 12.0f) == 43.75f);
expect(math_util::percentage<int, int>(5, 0, 12) == 41);
expect(math_util::percentage<float, float>(20.5f, 0.0f, 100.0f) == 20.5f);
expect(math_util::percentage<float, float>(4.5f, 1.0f, 6.0f) == 70.0f);
expect(math_util::percentage<float, int>(20.5f, 0.0f, 100.0f) == 21);
expect(math_util::percentage<int, int>(4, 2, 6) == 50);
expect(math_util::percentage<int, int>(0, -10, 10) == 50);
expect(math_util::percentage<int, int>(-10, -10, 10) == 0);
expect(math_util::percentage<int, int>(10, -10, 10) == 100);
expect(math_util::percentage(10, 0, 100) == 10);
};
"percentage_to_value"_test = [] {
expect(math_util::percentage_to_value(50, 5) == 3);
expect(math_util::percentage_to_value<int, float>(50, 5) == 2.5f);
expect(math_util::percentage_to_value(0, 5) == 0);
expect(math_util::percentage_to_value(10, 5) == 1);
expect(math_util::percentage_to_value(20, 5) == 1);
expect(math_util::percentage_to_value(30, 5) == 2);
expect(math_util::percentage_to_value(40, 5) == 2);
expect(math_util::percentage_to_value(50, 5) == 3);
expect(math_util::percentage_to_value(100, 5) == 5);
expect(math_util::percentage_to_value(200, 5) == 5);
expect(math_util::percentage_to_value(-30, 5) == 0);
};
}