Compile time positive and negative powers of two
Your code is not C++98 compliant

Standards prior to C++11 only allows const integer static member initialisation (see here).

So unfortunately your code is not C++98 compliant and in fact does not compile. So technically your code is off-topic on this site. As it is not working as intended. Your code probably only compiles because you're using a compiler that has an extension to allow non integer const static members.

To get around this typically you would define a static method that returns the value. In fact, this is why std::numeric_limits&lt;T&gt;::max() is a function instead of a static member value. However these cannot be evaluated in a constant expression context. You need C++11 constexpr for that afaik.

General advice

Some general advice. Template parameters are compile time constants by definition. Any sensible compiler should do any necessary casts during compile time so you will not get a run-time penalty for using higher precision. 

For this reason I advice that you use the largest types possible in your template to get the most precision at no additional cost. I.e. change float to double and int to long long. 

You should consider wrapping the templates that are not intended for use by the user in a suitable namespace. Typically I use a nested namespace called detail.

Also identifiers in ALL_CAPS_WITH_UNDERSCORES are typically reserved for macros. So I advice against using this naming convention for your identifiers as it will confuse many readers.

Better implementation

If we restrict ourselves to the bits of the code that are C++98 compliant, then we can have a much easier implementation for the integer exponentiation.

template&lt;unsigned long long exponent&gt;
struct ipow_2{
    static const unsigned long long value = (1 &lt;&lt; exponent);
};


If you want a C++98 compliant negative exponent you can use: 

template&lt;long long exponent&gt;
struct pow_2{
    static double value(){
        if (exponent == 0) {
            return 1;
        } 
        else if (exponent &gt; 0) {
            double half = pow_2&lt;exponent/2&gt;::value();
            return (1&lt;&lt;(exponent&amp;1))*half*half;
        }
        return 1 / pow_2&lt;-exponent&gt;::value();
    };
};


But be aware that the same caveat for non-integer const initialisation still applies so it's not hugely useful in TMP for example.

If we accept use C++11 you can simplify and generalize to:

// Tail call optimization will transform this into the equivalent 
// loop
constexpr int64_t ipow_p(int64_t base, int exp, int64_t ans = 1) {
    return exp &lt; 1 ?
        ans : ipow_p(base*base, exp/2, (exp % 2) ? ans*base : ans);
}

constexpr double ipow(int base, int exp){
    return exp &gt; 0 ? ipow_p(base, exp) : 1.0 / ipow_p(base, -exp);
}


This is usable in a constant (TMP) context thanks to the constexpr qualifier and At -O2 the call will be expanded to a constant.