出于兴趣,而不是现实生活中的要求:在JavaScript中减去两个数字的指数是否有可能?因为1e+29 * 1e-3
(或1e+29 / 1e+3
)的结果是不准确的数字9.999999999999999e+25
,即使正确的结果1e+26
可以用JavaScript表示。
答案 0 :(得分: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的工作示例。
答案 1 :(得分:0)
您可以使用Math.log(1e29)/Math.LN10
,但会产生28.999999999999993
。基数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
答案 2 :(得分:0)
您自然会将此视为浮点除法的结果,尤其是当一个数字比另一个数字小得多时。但是,如果数字具有相同的基数,也许你应该存储它们的指数。否则,您可以使用对数:
( Math.log(1e29) + Math.log(1e-3) ) / Math.LN10
> 25.999999999999993
您可能希望将该结果四舍五入到小数位,以处理不准确性并在基数10中获得结果。