Search code examples
c++gmppow

How can I check if std::pow will overflow double


I have a function that deals with arbitrarily large grids. I need to compute if a grid to the power of another number will fit into a double due to using std::pow. If it cannot, I want to take a different branch and use gnu multiprecision library instead of normal.

Is there a quick way to see if:

int a = 1024;
int b = 0-10;

if(checkPowFitsDouble(a, b)) {
    long c = static_cast<long>(std::pow(a, b)); //this will only work if b < 6
} else {
    mpz_t c; //yada yada gmp
}

I am completely stumped on checkPowFitsDouble; perhaps there is some math trick I don't know of.


Solution

  • A common trick to check whether exponentiations will overflow uses logarithms. The idea is based on these relationships:

    a^b <= m <=> log(a^b) <= log(m) <=> b * log(a) <= log(m) <=> b <= log(m) / log(a)

    For instance,

    int a = 1024;
    
    for (int b = 0; b < 10; ++b) {
        if (b * std::log(a) < std::log(std::numeric_limits<long>::max())) {
            long c = std::pow(a, b);
            std::cout << c << '\n';
        }
        else
            std::cout << "overflow\n";
    }
    

    This gives the idea. I hope this helps.