检查电源实现中的溢出

时间:2014-05-02 17:55:00

标签: java overflow pow

implement the power function这是一个常见的面试问题。我想知道最快的方法是找出是否发生溢出(使用日志功能太慢)。 这是一个好方法吗

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

   tempAnswer = pow(tempMult, bAbs / 2);

else
//overflow

1 个答案:

答案 0 :(得分:1)

浮点类型不会溢出,它们会“刷新到无穷大”(行为由IEEE-754定义/强制执行)。溢出条件可在机器代码级别(通过处理器标志等)检测到,但这显然不是高级语言的选项。您只能检查结果是否为+/-无穷大(Double.isInfinite(arg))。

因此,您显示的代码永远不会检测到aAbs * aAbs的溢出;除了NaN参数:

如果aAbs为负且溢出,则tempMult变为+ INFINITY, 如果aAbs为正且溢出,则tempMult变为+ INFINITY, 如果aAbs已经+/- INFINITY,则tempMult变为+ INFINITY和 如果aAbs是NaN,则tempMult也变为NaN。如果aAbs足够小,表达式也可以下溢(aAbs * aAbs == 0),但这不应该导致任何问题。

在NaN情况下,“(tempMult> = aAbs”的计算结果为false,因此您检测为溢出的唯一情况是NaN参数,这可能也不是您想要的。

这应该给出合理的结果,但是仍然不处理值+/- INFINITY或NaN的参数(如果需要,你需要显式处理这些参数):

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

所以要处理所有可能性:

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);
}