V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
rabbbit
V2EX  ›  JavaScript

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

  •  
  •   rabbbit · 2018-08-06 08:18:23 +08:00 · 4410 次点击
    这是一个创建于 2061 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 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

    第 1 条附言  ·  2018-08-06 08:53:31 +08:00

    发现了一个有趣的坑
    chrome

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

    后面那个才是精度问题导致的。
    fcten
        8
    fcten  
       2018-08-06 09:46:13 +08:00   ❤️ 1
    不完全是精度的问题,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
        9
    LeungJZ  
       2018-08-06 11:02:50 +08:00
    精度丢失吧。
    e8c47a0d
        10
    e8c47a0d  
       2018-08-08 13:03:48 +08:00
    V8 引擎的某种优化 feature ……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2784 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 37ms · UTC 15:27 · PVG 23:27 · LAX 08:27 · JFK 11:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.