Pooya
Pooya

Reputation: 399

Check overflow in power implementation

It's a common interview question to implement the power function. I'm wondering what the fastest way is to find out if overflow happens (using log function is too slow). Is it a good way to say

double tempMult= aAbs*aAbs;
if (tempMult >= aAbs) 

   tempAnswer = pow(tempMult, bAbs / 2);

else
//overflow

Upvotes: 1

Views: 368

Answers (1)

Durandal
Durandal

Reputation: 20059

Floating point types do not overflow, they "flush to infinity" (the behavior is defined/mandated by IEEE-754). The overflow condition is detectable at machine code level (through a processor flag etc.), but thats obviously not an option for high level languages. You can only check that the result is not +/- infinity (Double.isInfinite(arg)).

So the code you show will never detect an overflow for aAbs*aAbs; except for a NaN argument:

If aAbs is negative and overflows, tempMult becomes +INFINITY, if aAbs is positive and overflows, tempMult becomes +INFINITY, if aAbs is already +/- INFINITY tempMult becomes +INFINITY and if aAbs is NaN tempMult becomes NaN also. The expression can also underflow (aAbs * aAbs == 0), if aAbs is sufficiently small, but that shouldn't cause any issues.

In the NaN case, "(tempMult >= aAbs" evaluates as false, so the only case you detect as overflow is the NaN argument, which is probably also not what you intended.

This should give sane results, but it will still not handle arguments of value +/-INFINITY or NaN (you would need to explicitly handle these if desired):

double tempMult= aAbs*aAbs;
if (Double.isInfinite(tempMult)) {
    // overflow
} else {
    answer = pow(tempMult, bAbs / 2);
}

So to handle all eventualities:

if (Double.isNaN(aAbs) {
    // NaN
} else if (Double.isInfinite(aAbs)) { 
    // Infinity argument
}
double tempMult= aAbs*aAbs;
if (Double.isInfinite(tempMult)) {
    // overflow
} else {
    answer = pow(tempMult, bAbs / 2);
}

Upvotes: 1

Related Questions