maths: add renormalise function

This commit is contained in:
Danny Robson 2015-04-09 17:44:50 +10:00
parent afad51db9d
commit 9f6c17d6cf
2 changed files with 65 additions and 1 deletions

View File

@ -23,10 +23,11 @@
#include "debug.hpp" #include "debug.hpp"
#include "types/traits.hpp" #include "types/traits.hpp"
#include <cmath>
#include <cstdint> #include <cstdint>
#include <limits>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <cmath>
template <typename T> template <typename T>
T T
@ -307,6 +308,34 @@ smoothstep [[gnu::pure]] (T a, T b, T x)
return x * x * (3 - 2 * x); return x * x * (3 - 2 * x);
} }
#include "types/string.hpp"
//-----------------------------------------------------------------------------
template <typename T, typename U>
U
renormalise [[gnu::pure]] (T t)
{
static const T T_max = std::numeric_limits<T>::max ();
static const U U_max = std::numeric_limits<U>::max ();
static const bool shrinking = sizeof (U) < sizeof (T);
static const bool T_float = std::is_floating_point<T>::value;
static const bool U_float = std::is_floating_point<U>::value;
if (T_float && U_float)
return U (t);
if (T_float) {
return U (limit (t, 0, 1) * U_max);
}
if (U_float)
return U (t) / T_max;
if (shrinking)
return U (t / (sizeof (T) / sizeof (U)));
else
return U (t) * (sizeof (U) / sizeof (T));
}
#include "maths.ipp" #include "maths.ipp"

View File

@ -51,6 +51,39 @@ test_comparisons (void)
} }
void
test_normalisations (void)
{
// u8 to float
{
auto a = renormalise<uint8_t,float> (255);
CHECK_EQ (a, 1.f);
auto b = renormalise<uint8_t,float> (0);
CHECK_EQ (b, 0.f);
}
// float to u8
{
struct {
float a;
uint8_t b;
} TESTS[] = {
{ 1.f, 255 },
{ 0.f, 0 },
{ 2.f, 255 },
{ -1.f, 0 }
};
for (auto i: TESTS) {
std::cerr << "x";
auto v = renormalise<decltype(i.a),decltype(i.b)> (i.a);
CHECK_EQ ((unsigned)v, (unsigned)i.b);
}
}
}
int int
main (int, char **) { main (int, char **) {
// Max out the precision in case we trigger debug output // Max out the precision in case we trigger debug output
@ -59,6 +92,8 @@ main (int, char **) {
test_comparisons (); test_comparisons ();
test_normalisations ();
CHECK_EQ (util::min (-2, 0, 2), -2); CHECK_EQ (util::min (-2, 0, 2), -2);
CHECK_EQ (util::max (-2, 0, 2), 2); CHECK_EQ (util::max (-2, 0, 2), 2);