sok*_*npk 6 javascript floating-point
一位朋友告诉我(至少在谷歌Chrome控制台中)以下语句打印为true:
1/Math.pow(0.9999999999999999, Number.MAX_SAFE_INTEGER) === Math.E
Run Code Online (Sandbox Code Playgroud)
的确,1/Math.pow(0.9999999999999999, Number.MAX_SAFE_INTEGER)
是2.718281828459045
.
这不是巧合吗?!
有人可以解释幕后发生的事情吗?
根据wolfram alpha,正确的值应1/0.40628
近似2.4613566998129373
- 大约- 非常远离Math.E
.(我假设wolframalpha在计算中比javascript更精确,但我可能错了).
任何解释将不胜感激.
额外奖励:我想知道这个表达式的真正近似数学值是多少?我找到了这个:
n = 0.0000000000000001
(1 - n)^MAX_INT = 1 + (MAX_INT choose 2) * n + (MAX_INT choose 3) * n^2 + ... + n^MAX_INT
Run Code Online (Sandbox Code Playgroud)
但我不知道如何近似.
我在wolfram alpha中测试了上面的表达式并得到了2.46
它.
pow(x, y)
通常计算为exp(log(x) * y)
,所以让我们从那里开始.
我们有:
x = 0.9999999999999999
,转到x = 1 - eps
(哪里eps == 2^-53
).y = 2^53 - 1
即y = 1 / eps
(大约).所以我们实际上在计算exp(log(1 - eps) * 1/eps)
.
该泰勒级数展开的log(1 - k)
是-k - k^2/2 - ...
,但在我们的情况下,所有的高阶项将被截断.
所以我们有exp(-eps / eps)
,或者exp(-1)
,是1 / e
.
1 - 0.9999999999999999 // 1.1102230246251565e-16
Math.log(1 - 1.1102230246251565e-16) // -1.1102230246251565e-16
1 / Number.MAX_SAFE_INTEGER // 1.1102230246251568e-16
Run Code Online (Sandbox Code Playgroud)