/*
Function to get the maximum possible number of places a numeric type could hypothetically represent under ideal circumstances.
Copyright (C) 2015 Peter R. Bloomfield
Web: avidinsight.uk

This code is made freely available under the terms of the MIT open source license.
*/

#include <iostream>
#include <cmath>
#include <limits>

using namespace std;

// Get the maximum number of radix 
template <typename T_type, int T_radix>
int getMaxPlaces()
{
    static_assert(
        T_radix > 1,
        "Radix must be at least 2."
    );
    static_assert(
        std::numeric_limits<T_type>::is_specialized,
        "Numeric limits traits info not found."
    );

    // Integers contain no point.
    if (std::numeric_limits<T_type>::is_integer)
        return 0;

    // Maximum number of places in the native radix.
    const int places =
        std::abs(std::numeric_limits<T_type>::min_exponent) +
        std::numeric_limits<T_type>::digits;

    // Special case: If the requested radix matches the underlying radix
    //  specified in traits then no base conversion is necessary.
    if (T_radix == std::numeric_limits<T_type>::radix)
        return places;

    // Convert the number of places to the requested radix.
    return static_cast<int>( std::ceil(
        places *
        std::log(std::numeric_limits<T_type>::radix) /
        std::log(T_radix)
    ));
}

int main() {
	cout << "int:         " << getMaxPlaces<int, 10>() << endl;
	cout << "float:       " << getMaxPlaces<float, 10>() << endl;
	cout << "double:      " << getMaxPlaces<double, 10>() << endl;
	cout << "long double: " << getMaxPlaces<long double, 10>() << endl;
	return 0;
}