JavaScript中的减指数

JavaScript中的减指数,javascript,numbers,double,Javascript,Numbers,Double,出于兴趣,而不是现实生活的需要:在JavaScript中是否有可能减去两个数字的指数?因为1e+29*1e-3(或1e+29/1e+3)的结果是不精确的数字9.9999999999E+25,即使正确的结果1e+26可以用JavaScript表示。必须有更简洁的方法来做,但一个选项是将数字转换为字符串,对其进行操作,然后将其转换回数字: function exp_add(num,exp) { var split = num.toExponential().split('e'); v

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

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

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

工作示例位于。

您可以使用
Math.log(1e29)/Math.LN10
,但是这会产生
28.999999993
。对于这些数字,基数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
函数toExp(num){
返回num.toExponential().split(“e”).map(Number);
//num.toString()仅适用于num=1e21
}
函数fromExp(exp){
返回exp[0]*Math.pow(10,exp[1]);
//或:parseFloat(exp[0]+“e”+exp[1]);
}
函数(a,b){
返回[a[0]*b[0],a[1]+b[1]];
}
函数expDivide(a,b){
返回[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

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

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

您可能希望将该结果四舍五入到小数点后几位,以消除不精确性,并以10为基数获得结果。

您可能会发现这个问题很有趣: