#include <cmath>
#include <limits>
#include <iostream>
#define MAX_DECIMAL_FRACTION 5
#define DEBUGTRACE(x) // do { std::cerr << x; } while (false)
template <typename T, bool is_integer> struct reverse_impl;
template <typename T>
struct reverse_impl<T, true>
{
static T reverse(T input)
{
T output;
for (output = 0; input; input/=10)
output = (output * 10) + input % 10;
return output;
}
};
template <typename T>
struct reverse_impl<T, false>
{
static T reverse(T input)
{
if (std::abs(input) <= std::numeric_limits<T>::epsilon())
return T(0);
// scale input
int log10 = (int) (std::log(input)/std::log(T(10)));
input *= std::pow(10, MAX_DECIMAL_FRACTION);
input = std::floor(input);
input /= std::pow(10, log10+MAX_DECIMAL_FRACTION);
DEBUGTRACE("debug: scaled " << input << " digits: ");
int iteration = std::max(log10+MAX_DECIMAL_FRACTION, MAX_DECIMAL_FRACTION);
if (std::floor(input) < 1)
{
input *= 10;
iteration--;
}
T output;
for (output = T(0);
iteration-- && std::floor(input) >= 1;
input-=std::floor(input), input*=T(10))
{
output = (output / T(10)) + std::floor(input);
DEBUGTRACE(std::floor(input));
}
DEBUGTRACE(std::endl);
return output * std::pow(10, log10);
}
};
template <typename T>
T reverse(T input)
{
return reverse_impl<T, std::numeric_limits<T>::is_integer>::reverse(input);
}
int main()
{
std::cout << reverse(-123l) << std::endl;
std::cout << reverse(123ul) << std::endl;
std::cout << reverse(123456.0) << std::endl;
std::cout << reverse(0.027f) << std::endl;
return 0;
}