0.1+0.2不等于0.3

作者: 羽晞yose | 来源:发表于2020-06-13 15:20 被阅读0次

    在计算机里,所有的数据都会转化为二进制被存储
    而0.1和0.2是十进制,它们需要转换为二进制被存储

    先以整数为例
    10转化为二进制就是1010,怎么算出来的?
    1 * 2^3 + 0 * 2² + 1 * 2^1 + 0 * 2 = 8+2 = 10
    反过来说,1010总共有四位,第一位为0乘以2的零次方,第二位为1乘以2的一次方,以此方式计算下去

    那么小数又是如何计算的
    以0.5来说,就是1乘以2的负一次方
    小数点后的二进制计算规律为:位数越往后计算方式为2的负N次方,N递减1

    那么0.1转换成2进制又是怎么算的?
    当然用上面的N递减1来算很麻烦,所以真正使用的是乘2取整法
    以0.1为例:

    0.1 * 2 = 0.2; // 无整数,填0 => 0.0
    0.2 * 2 = 0.4; // 无整数,填0 => 0.00
    0.4 * 2 = 0.8; // 无整数,填0 => 0.000
    0.8 * 2 = 1.6; // 去整数,填1,余0.6 => 0.0001
    0.6 * 2 = 1.2; // 去整数,填1,余0.2 => 0.00011
    0.2 * 2 = 0.4; // 无整数,填0 => 0.000110
    

    根据上面的结果可以看出,0.1转化为二进制会是一个无限循环小数(双精度浮点数),而计算机不可能一直存储下去,所以会在限定位数取整(IEEE 754 标准的 64 位双精度浮点数的小数部分最多支持53位二进制位)

    0.1.toString(2); // 0.0001100110011001100110011001100110011001100110011001101
    

    正常规律讲,其实后面依然为0011,但是长度已经超过最大值,所以对下一位进行取整,由于下一位是1,所以最后一位则从0变为1,因此实际存储结果会比0.1更大一些
    0.0001100110011001100110011001100110011001100110011001101 // 取整后
    0.000110011001100110011001100110011001100110011001100110011 // 正常结果

    0.2也是如此,其结果依然会比0.2大一些

    0.2.toString(2); // 0.001100110011001100110011001100110011001100110011001101
    

    那么0.1的二进制 加上 0.2的二进制,其结果就为
    0.0100110011001100110011001100110011001100110011001100111
    该值转为10进制,则结果为0.30000000000000004

    所以,0.1+0.2不等于0.3
    参考文章:为什么在JavaScript中0.1+0.2不等于0.3?


    == 和 === 的区别?

    ===会比较数据类型,那么什么时候会用到双等号呢?
    null == undefined的时候

    相关文章

      网友评论

        本文标题:0.1+0.2不等于0.3

        本文链接:https://www.haomeiwen.com/subject/tzjatktx.html