2

出于兴趣而不是现实生活的需求:是否有可能在 JavaScript 中减去两个数字的指数?因为1e+29 * 1e-3(或1e+29 / 1e+3)的结果是不精确的数字9.999999999999999e+25,即使正确的结果1e+26可以用 JavaScript 表示。

4

3 回答 3

0

必须有更简洁的方法,但一种选择是将您的数字转换为字符串,对其进行操作,然后将其转换回数字:

function exp_add(num,exp) {
    var split = num.toExponential().split('e');
    var exponent = parseInt(split[1],10);
    exponent += exp;
    return parseFloat(split[0] + "e" + exponent);
}

jsFiddle的工作示例。

于 2013-02-23T01:06:16.557 回答
0

您可以使用Math.log(1e29)/Math.LN10,但是会产生28.999999999999993. Base 2 对这些数字来说是不精确的。所以我们最后的手段是Number.prototype.toString,它正确地产生了"1e29"。我们现在如何使用它?

function toExp(num) {
    return num.toExponential().split("e").map(Number);
    // num.toString() only works for num <= 1e-6 and num >= 1e21
}
function fromExp(exp) {
    return exp[0] * Math.pow(10, exp[1]);
// or:     parseFloat(exp[0]+"e"+exp[1]);
}

function expMultiply(a, b) {
    return [ a[0]*b[0], a[1]+b[1] ];
}
function expDivide(a, b) {
    return [ a[0]/b[0], a[1]-b[1] ];
}

> fromExp(expMultiply(toExp(1e29), toExp(1e-3)))
1e+26
> fromExp(expDivide(toExp(1e29), toExp(1e3)))
1e+26
于 2013-02-23T01:13:19.963 回答
0

您自然会看到这是浮点除法的结果,尤其是当一个数字远小于另一个数字时。但是,如果数字具有相同的底数,也许你应该只存储它们的指数。否则,您可以使用对数:

( Math.log(1e29) + Math.log(1e-3) ) / Math.LN10
> 25.999999999999993

您可能只想将该结果四舍五入到小数点后几位,以处理不准确性并获得以 10 为底的结果。

于 2013-02-23T01:16:30.243 回答