对JavaScript的Math.pow()函数的一个修正

一、问题:

JavaScript的Math对象中有一个方法Math.pow(x, y),用来求x的y次方。它有一个问题,即当x<0且y<1的时候,它总是返回NaN。对于x<0且1/y为偶数时,它返回NaN是有道理的,因为负数不能够被开偶数次方根。但是对于x<0且1/y为奇数时,返回NaN就没有道理了,因为负数也可以被开奇数次方根。

即JavaScript的Math.pow(x, y)方法,不支持对负数求奇次方根。

举例来说明:

测试用例

说明

JavaScript 返回结果

实际应返回结果

是否通过测试?

Math.pow(16, 1/2) 16^(1/2),即对16开平方 4 4 通过
Math.pow(-16, 1/2) (-16)^(1/2),即对-16开平方 NaN NaN 通过
Math.pow(27, 1/3) 27^(1/3),即对27开立方 3 3 通过
Math.pow(-27, 1/3) (-27)^(1/3),即对-27开立方 NaN -3 失败!

注:以上均在实数范围内讨论。

二、问题原因:

估计JavaScript的Math.pow(x, y)方法,是使用对数逼近的途径来对x的奇次方根求解的,而对数函数的定义域不包括负数,于是产生了这个问题。

三、解决方案:

    Math.power = Math.pow;
    //
    // 让Math.pow(x, y)支持对x求奇次方根
    //
    Math.pow = function (x, y) {
        if (y < 1 && 1 / y % 2 == 1 && x < 0) {
            return -Math.power(-x, y);
        } else {
            return Math.power(x, y);
        }
    };

四、检验:

在进行修正后,再运行以上的测试用例,则全部通过。

测试用例

说明

修正后JavaScript 返回结果

实际应返回结果

是否通过测试?

Math.pow(16, 1/2) 16^(1/2),即对16开平方 4 4 通过
Math.pow(-16, 1/2) (-16)^(1/2),即对-16开平方 NaN NaN 通过
Math.pow(27, 1/3) 27^(1/3),即对27开立方 3 3 通过
Math.pow(-27, 1/3) (-27)^(1/3),即对-27开立方 -3 -3 通过

Add comment

Loading