浮点数一些设计原理

作者: 梁同桌 | 来源:发表于2017-08-07 14:01 被阅读81次

    摘要:本篇文章会讲述浮点数的设计原理,比如如何存储二进制的问题,从而帮助我们更好的编码。

    __1. deading code __

    console.log(1.0-0.9 == 0.1);
    //输出 false
    console.log(1.0-0.9, 0.1);
    //输出 0.09999999999999998 0.1
    //所以判断浮点运算结果前要对参数进行精度缩小,缩小精度会四舍五入。
    console.log(parseFloat((1.0-0.9).toFixed(10)) == 0.1);
    //输出 true 
    console.log(parseFloat((1.0-0.9).toFixed(10)),0.1)   
    //输出 0.1 0.1
    

    所以使用 JavaScript 设计浮点数计算时,要考虑小数不准确的问题。

    2.浮点数二进制存储

    如 32 存储为例来讲解存储。

    Sign Exponent Mantissa
    1bit 8bits 23bits
    • Sign:表示浮点数是正数还是负数。0表示正数,1表示负数
    • Exponent:指数部分。类似于科学技术法中的M*10^N中的 N,要注意规定
      01111111 = 2^0 也就是 0,所以指数部分可以表达: -128 - 127
    • Mantissa:基数部分。浮点数具体数值的实际表示。

    尝试把 3.1 转换成二进制存储:

    1. 是正数第一位是 0
    2. 3 转换成二进制 11
    3. 0.1 转换成二进制,__0.1 __ 转换成 0.0625+0.007825+0.00390625... 即 2-3+2-4+2^7....,二进制为 .00011001100110011001100 ,是1100无限循环,保留到23位。(这里确实有点绕,不理解的单独查资料能更快了解。也就是这里导致小数在计算机里的存储会不准确,是一个近似值。
    4. 整数和小数合并为 11.0001100110011001100110 , 然后保证小数点以前只有一位数,1.10001100110011001100110 * 2^1
    5. 合并后小数点前的一位数是要舍去的,由于我们上一个步骤,小数点前的数字总会为 1,所以为了减少存储我们舍去 . 前的为1数字,最后得 .100011001100110011001100 * 2^1
    6. 指数转换,由上一步得指数为 __2^1 __,由于规定 01111111 = 2^0(这样的目的就是为了,指数可以为正也可以为负), 2^110000000 ,合并后得
      10000000 10001100110011001100110
    7. 添上第一位代表正负 0 10000000 10001100110011001100110 最终__ 3.1 __被用二进制表达。

    其中最重要的部分是小数转二进制,像 0.5、0.25、0.125 这样的小数转化二进制为 0.1、0.01、0.001 ,但是 0.1、0.2 就不好表示了。如果不理解百度有在线二转十进制 地址

    验证的网址:https://www.h-schmidt.net/FloatConverter/IEEE754.html

    3.猜想

    语言还没有组织好。

    我的博客:http://liangtongzhuo.com

    相关文章

      网友评论

        本文标题:浮点数一些设计原理

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