为什么 Math.pow 和 ** 和循环相乘 得到的结果不同?

2018-08-06 08:18:23 +08:00
 rabbbit

在 chrome 中测试

Math.pow(1.618033988749895, 8)
// 46.97871376374779
1.618033988749895**8
// 46.978713763747805
1.618033988749895*1.618033988749895*1.618033988749895*1.618033988749895*1.618033988749895*1.618033988749895*1.618033988749895*1.618033988749895
// 46.9787137637478

http://www.wolframalpha.com/input/?i=1.618033988749895**8

4581 次点击
所在节点    JavaScript
10 条回复
john990
2018-08-06 08:26:42 +08:00
double 丢失精度
metorm
2018-08-06 08:30:38 +08:00
浮点数零度问题,没啥新鲜的……
metorm
2018-08-06 08:31:00 +08:00
@metorm 写错了,精度问题
mringg
2018-08-06 08:55:06 +08:00
1.0!=1.0
xiaody
2018-08-06 09:04:50 +08:00
循环相乘就算了,毕竟精度问题 2.2 * 100 != 2.2 * 10 * 10。
Math.pow 和 ** 不等应该是 V8 的 ** 实现问题,Firefox 里是相等的,参考 https://bugs.chromium.org/p/v8/issues/detail?id=5848
em2046
2018-08-06 09:23:09 +08:00
整数用 BigInt 计算,小数可以移动小数点
y=50n
y**y === 50n**50n
//true
maichael
2018-08-06 09:40:01 +08:00
没记错的话,Math.pow 和 ** 不相等等应该是 Chrome 实现的问题,https://segmentfault.com/a/1190000008217150

后面那个才是精度问题导致的。
fcten
2018-08-06 09:46:13 +08:00
不完全是精度的问题,V8 的运行时实现有缺陷

99**99 // 3.697296376497268e+197
Math.pow(99,99) // 3.697296376497263e+197
var a = 99;
a ** a // 3.697296376497263e+197

第一个结果不同,是因为它是编译时计算的。V8 在编译时和运行时计算使用了不同的代码。事实上,编译时计算的结果更准确。

99**99=369729637649726772657187905628805440595668764281741102430259972423552570455277523421410650010128232727940978889548326540119429996769494359451621570193644014418071060667659301384999779999159200499899

https://stackoverflow.com/questions/41679191/why-is-math-pow-sometimes-not-equal-to-in-javascript/41679584
LeungJZ
2018-08-06 11:02:50 +08:00
精度丢失吧。
e8c47a0d
2018-08-08 13:03:48 +08:00
V8 引擎的某种优化 feature ……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/477128

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX