feat: Add math_util::percentage_to_value
This commit is contained in:
parent
7905f37462
commit
bc67e64e79
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
44
tests/unit_tests/utils/math.cpp
Normal file
44
tests/unit_tests/utils/math.cpp
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user