Normalized integer to / from floating conversion

I need to convert normalized integer values ​​to and from real floating point values. For example, for int16_t, a value of 1.0 is represented by 32767, and -1.0 is represented by -32768. Although it is a little tedious to do this for every integer type, both signed and unsigned, it is still fairly easy to write manually.

However, I want to use standard methods when possible, instead of leaving and reinventing the wheel, so what I'm looking for looks like a standard C or C ++ header, Boost library, or some other small, easily included source that is already performs these conversions.

+4
source share
2 answers

Here's a template solution using std::numeric_limits:

#include <cstdint>
#include <limits>

template <typename T>
constexpr double normalize (T value) {
  return value < 0
    ? -static_cast<double>(value) / std::numeric_limits<T>::min()
    :  static_cast<double>(value) / std::numeric_limits<T>::max()
    ;
}

int main () {
  // Test cases evaluated at compile time.
  static_assert(normalize(int16_t(32767)) == 1, "");
  static_assert(normalize(int16_t(0)) == 0, "");
  static_assert(normalize(int16_t(-32768)) == -1, "");
  static_assert(normalize(int16_t(-16384)) == -0.5, "");
  static_assert(normalize(uint16_t(65535)) == 1, "");
  static_assert(normalize(uint16_t(0)) == 0, "");
}

This handles both signed and unsigned integers, and 0 normalizes to 0.

+7
source

Although it is a little tedious for this for each integer type, both signed and unsigned, it is still fairly easy to write manually.

You certainly do not need to do this for every integer type! Use instead <limits>.

template<class T> double AsDouble(const T x) {
    const double valMin = std::numeric_limits<T>::min();
    const double valMax = std::numeric_limits<T>::max();
    return 2 * (x - valMin) / (valMax - valMin) - 1; // note: 0 does not become 0.
}
-2
source

All Articles