maths: add renormalise function
This commit is contained in:
parent
afad51db9d
commit
9f6c17d6cf
31
maths.hpp
31
maths.hpp
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user