math: add function for clamping parts of a rational to max value

This commit is contained in:
Moritz Bunkus 2018-10-11 16:18:27 +02:00
parent da6fe3820a
commit 66effd98c2
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
3 changed files with 24 additions and 0 deletions

View File

@ -48,4 +48,20 @@ int_to_double(int64_t value) {
return std::ldexp(((value & ((1ll << 52) - 1)) + (1ll << 52)) * (value >> 63 | 1), (value >> 52 & 0x7ff) - 1075);
}
int64_rational_c
clamp_values_to(int64_rational_c const &r,
int64_t max_value) {
auto num = r.numerator();
auto den = r.denominator();
if (!num || !den || ((num <= max_value) && (den <= max_value)))
return r;
// 333 / 1000 , clamp = 500, mul = 1/2 = 1/(max/clamp) = clamp/max
auto mult = int64_rational_c{ max_value, std::max(num, den) };
den = boost::rational_cast<int64_t>(den * mult);
return { boost::rational_cast<int64_t>(num * mult), den ? den : 1 };
}
}}

View File

@ -41,6 +41,7 @@ count_1_bits(uint64_t value) {
uint64_t round_to_nearest_pow2(uint64_t value);
int int_log2(uint64_t value);
double int_to_double(int64_t value);
int64_rational_c clamp_values_to(int64_rational_c const &r, int64_t max_value);
// Converting unsigned int types to signed ints assuming the
// underlying bits in memory should represent the 2's complement of a

View File

@ -67,4 +67,11 @@ TEST(Math, ToSigned) {
EXPECT_EQ(-3, mtx::math::to_signed(static_cast<int64_t>(-3)));
}
TEST(Math, ClampValueTo) {
EXPECT_EQ((int64_rational_c{ 0, 1}), mtx::math::clamp_values_to({ 0, 1}, 65535));
EXPECT_EQ((int64_rational_c{ 4'711, 815}), mtx::math::clamp_values_to({ 4'711, 815}, 65535));
EXPECT_EQ((int64_rational_c{65'535, 21'844}), mtx::math::clamp_values_to({ 1'000'000, 333'333}, 65535));
EXPECT_EQ((int64_rational_c{65'535, 1}), mtx::math::clamp_values_to({999'999'999, 1}, 65535));
}
}