美文网首页JavaScript
IEEE754浮点数格式与Javascript Number的特

IEEE754浮点数格式与Javascript Number的特

作者: 西瓜鱼仔 | 来源:发表于2020-08-25 13:39 被阅读0次

    Javascript作为一门动态语言,其数字类型只有Number一种。 Nubmer类型使用的就是IEEE754标准中的 双精度浮点数。Javascript数字的许多特性都依赖于此标准,例如令人费解的0.1+0.2不等于0.3。

    这篇文章介绍IEEE754标准中双精度浮点数二进制储存格式,并由此推出js中数字的一些特性。

    一、IEEE754中浮点数的储存格式

    在IEEE754中,双精度浮点数储存为64位:


    指数位可以通过下面的方法转换为使用的指数值:


    浮点数表示的值的形式由 ef 确定:

    二、javascript Number的特性

    在js中Number对象上附带了许多属性,表示可数的范围等信息,例如Number.MAX_SAFE_INTEGER是一个16位的数字,这一部分将解释如何计算出这些有特殊意义的数字。

    1.计算Number.MAX_VALUE和Number.MIN_VALUE

    当符号位为0、指数取到1023、小数位全为1时,为可表示的最大值
    当符号位为0、指数位全为0(表示非规格浮点数)、小数位仅最后一位为1时,为可表示的最小正值

    var max = (-1)**0 * 2**1023 * (Number.parseInt( "1".repeat(53) ,2) * 2**-52);
    max === Number.MAX_VALUE;
    // true
    
    var min = (-1)**0 * 2**-1022 * (Number.parseInt( "0".repeat(52)+"1" ,2) * 2**-52);
    min === Number.MIN_VALUE;
    // true
    

    2.计算Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER

    Number.MAX_SAFE_INTEGER表示最大安全整数,它是9开头的16位数字,也表明js Number最大精度不超过16位。
    ECMASCRIPT-262定义:

    The value of Number.MAX_SAFE_INTEGER is the largest integer n such that n and n + 1 are both exactly representable as a Number value.
    http://www.ecma-international...

    改变指数位为53,这让每个小数位都表示浮点数的整数部分,小数位最低位对应 2^0,然后将每个小数位都置1,可得最大准确整数:

    var max_safe_int = (-1)**0 * 2**52 * (Number.parseInt("1".repeat(53),2) * 2**-52);
    max_safe_int === Number.MAX_SAFE_INTEGER;
    // true
    //当它 +1 时,可由 (-1)**0 * 2**53 * (Number.parseInt("1"+"0".repeat(52),2) * 2**-52) 正确表示,而再 +1 时则无法准确表示
    
    //符号位取反可得最小安全整数
    -1 * max_safe_int === Number.MIN_SAFE_INTEGER;
    

    3.计算Number.EPSILON

    Number.EPSILON是一个极小值,用于检测计算结果是否在误差范围内。例如:

    Math.abs(0.1 + 0.2 - 0.3) < Number.EPSILON;
    // true
    
    //2017-9-27 补充
    1.1 + 1.3 - 2.4 < Number.EPSILON
    // false
    

    根据ECMASCRIPT-262定义:

    The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 x 10‍−‍16.
    http://www.ecma-international...

    根据定义Number.EPSILON是大于1的最小可表示数与1的差,可以据此计算出Number.EPSILON的值:

    //将表示1的二进制小数位的最左端置1,可表示大于1的最小数
    var epsilon = (-1)**0 * 2**0 * (Number.parseInt("1"+"0".repeat(51)+"1",2) * 2**-52) - 1;
    // (-1)**0 * 2**0 * (+`0b1${"0".repeat(51)}1` * 2**-52) - 1;
    epsilon === Number.EPSILON;
    // true
    

    原文:https://segmentfault.com/a/1190000008268668

    相关文章

      网友评论

        本文标题:IEEE754浮点数格式与Javascript Number的特

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