zoukankan      html  css  js  c++  java
  • 为什么0.1 + 0.2 != 0.3 ???

    1、JavaScript计算的翻车现场

     

        所以,为什么会出现这样的结果呢?哪些计算又会出现这样的问题呢,让我们一步步的来分析一下~~~

    2、JavaScript是如何表示数字的

    • 计算机遵循 IEEE 754 标准 ,是将信息转化为二进制进行存储的,JavaScript使用Number类型表示数字(整数和浮点数),而JS采用的是双精度版本,也就是通过64位来表示一个数字,具体如下:(1 + 11 + 52)

           注意:虽然只有52位来表示有效数字,但是JS的最大安全数字是JS_NUMBER_MAX_SAFE_INTEGER == Math.pow( 2,53)-  1 而不是Math.pow( 2,52)-  1(转成整数就是16位),这是因为二进制表示有效数字总是1.xx…xx的形式,尾数部分f在规约形式下第一位默认为1(省略不写,xx..xx为尾数部分f,最长52位)。因此,JavaScript提供的有效数字最长为53个二进制位(64位浮点的后52位+被省略的1位)

    3、运算时发生了什么

        一、进制转换

    • 十进制整数转化为二进制整数(除2取余,自下而上,逆序排列)

    • 十进制小数转化为二进制小数(乘2取整,自上而下,顺序排列)

              由上面可知:173 -----> 10101101

                                    0.8125 -----> 0.1101

                                    173.8125 -----> 10101101.1101

    • 工具中直观的表示两者在计算机内存中的表现形式
      • 0.1 -----> 0 0011 0011 0011.....(无限循环)

      • 0.2 -----> 0011 0011 0011.....(无限循环)

    2

    • 由此可以看出,0.1与0.2都是无限循环小数,JS的双精度版本会对这种小数的二进制进行取有效位数,从而造成精度丢失。
    • 由于JS的最大安全数字是16位,因此我们可以通过number.toPrecision(16)来进行精度运算,超过的部分会自动进行凑整处理。

    二、对阶运算

    • 由于指数位数不相同,运算时需要进行对阶运算,因此也有可能造成精度丢失。

    !!!结果:精度丢失可能出现在进制转化或者对阶运算中

    3、以后如何解决

    • Number.prototype.toFixed(digits)精度为0-20之间,返回一个数值的字符串形式
    • Math.js
    • big.js
    • 等等

    4、参考资料(哈哈哈,尊重作者,其实我就是写了一遍加深记忆~~~)

    北栀女孩儿
  • 相关阅读:
    网络基础
    关于actionscript中新建一个sprite,设置大小(宽高)的问题。
    Android SDK无法更新问题解决 ---- 还可解决无法上google的问题
    android apk简单反编译
    Flash的坑之ExternalInterface.call只返回null值的解决办法
    Flash Socket简单调试工具
    进制转换 正进制
    Codeforces Div3 #498 A-F
    UVa10082
    div与div之间的拖拽
  • 原文地址:https://www.cnblogs.com/wxh0929/p/14478545.html
Copyright © 2011-2022 走看看