• 语法》第三章 数值


    (本文为阮一峰js标准教程的学习笔记,旨在总结该教程中涉及的知识点大纲及个人所做的一些拓展,方便作为“目录”或者“大纲”复习和查漏补缺,详细内容请参见阮一峰教程原文)

    第二部分 语法

    **********第三章 数值***************

    一.概述
    1.所有数都是以64位浮点数形式储存的。1与1.0相同(8bit、也就是64位二进制数)
    2、JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。
    3、由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
    0.1 + 0.2 === 0.3
    // false

    0.3 / 0.1
    // 2.9999999999999996

    (0.3 - 0.2) === (0.2 - 0.1)
    // false


    4、容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算,参见《运算符》一节的”位运算“部分。

    二、数值精度
    1、国标IEEE754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

        第1位:符号位,0表示正数,1表示负数
        第2位到第12位:指数部分
        第13位到第64位:小数部分(即有效数字)

    IEEE 754 规定,有效数字第一位默认总是1,不保存在64位浮点数之中。因此,JavaScript 提供的有效数字最长为53个二进制位。

    2.精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-(2的53次方-1)到2的53次方-1,都可以精确表示。【内部细节不详】
    Math.pow(2, 53)
    // 9007199254740992

    Math.pow(2, 53) + 1
    // 9007199254740992

    Math.pow(2, 53) + 2
    // 9007199254740994

    Math.pow(2, 53) + 3
    // 9007199254740996

    Math.pow(2, 53) + 4
    // 9007199254740996

    Math.pow(2, 53)
    // 9007199254740992

    // 多出的三个有效数字,将无法保存
    9007199254740992111
    // 9007199254740992000

    三.数值范围
    1.64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。
    分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。
    2.指数部分等于或超过最大正值1024,JavaScript 会返回Infinity “正向溢出”;
    3.指数等于或超过最小负值-1023(即非常接近0),JavaScript 会直接把这个数转为0,“负向溢出”。

    var x = 0.5;

    for(var i = 0; i < 25; i++) {
      x = x * x;
    }

    x // 0

    4.js能表示的最大值和最小值,JavaScript 提供Number对象的MAX_VALUE和MIN_VALUE属性表示。

    Number.MAX_VALUE // 1.7976931348623157e+308
    Number.MIN_VALUE // 5e-324

    四、数值的表示法
    1、使用字面量表示  比如:  0xFF(十六进制)
    2、科学计数法,允许字符e或E后跟一个整数,表示*10的多少次方。
    3、js自动将数值转科学技术法的几种情况(其他均用字面量形式表示)
    (1)小数点前的数字多于21位。

    1234567890123456789012
    // 1.2345678901234568e+21

    123456789012345678901
    // 123456789012345680000

    (2)小数点后的零多于5个。

    // 小数点后紧跟5个以上的零,
    // 就自动转为科学计数法
    0.0000003 // 3e-7

    // 否则,就保持原来的字面形式
    0.000003 // 0.000003

    五、数值的进制
    1.使用字面量时,js对整数提供四种进制。
    十进制 没有前导0
    十六 前导0x或0X
    八 0o 或者0O
    二 0b 或者0B


    2. 特殊:单独的前导0--前导0表示八进制,处理时很容易造成混乱。ES5的严格模式和ES6,已经废除了这种表示法,但是浏览器目前还支持。
    通常来说,有前导0的数值会被视为八进制,但是如果前导0后面有数字8和9,则该数值被视为十进制。

    0888 // 888 十进制
    0777 // 511 被认为是八进制


    3.默认js将十六、八、二自动转十(js依赖先导辨认)
    4.前导标明进制,又出现不属于该进制数字报错。


    六、特殊数值
    1、正零和负零
    1.1js内部有两个0,+0和-0是等价的/
    1.2严格相等+0===-0 +0 -0  0
    1.3js中任何一个数都有负值,0不例外;【不讨论NaN】
    1.4唯一区别场合:+0和-0当作分母,返回值不相等;
    (1/+0)===(1/-0) //false;
    原因:一个得到+Infinity 另一个-Infinity

    2.NaN
    2.1含义:表示非数字
    2.2主要出现场景:将字符串转为数字;
    2.3一些函数运算结果出现NaN
    Math.acos(2) // NaN
    Math.log(-1) // NaN
    Math.sqrt(-1) // NaN

    2.4
    0 / 0 // NaN

    2.5,NaN不是一种独立的数据类型,而是一种特殊数值,它的数据类型依然属于Number,使用typeof运算符可以看得很清楚。

    typeof NaN // 'number'

    2.6运算规则:
    *不等于任何值,包括自身NaN === NaN // false
    *由于数组的indexOf方法,内部使用的是严格相等运算符,所以该方法对NaN不成立。

    [NaN].indexOf(NaN) // -1
    *Boolean(NaN) // 转布尔false
    *与任何数包括自己运算都是NaN
    *

    2.7 判断NaN方法
    2.7.1 isNaN方法:遇到NaN或者可以被转成NaN的值返回true;
       *只对数有效,传入其他值自动转。
       *传入字符串也会为true;
       *isNaN返回true可能是NaN,也可能是别的比如字符串.
    isNaN('Hello') // true
    // 相当于
    isNaN(Number('Hello')) // true

    出于同样的原因,对于对象和数组,isNaN也返回true。

    isNaN({}) // true
    // 等同于
    isNaN(Number({})) // true

    isNaN(['xzy']) // true
    // 等同于
    isNaN(Number(['xzy'])) // true

    但是,对于空数组和只有一个数值成2.72员的数组,isNaN返回false。

    isNaN([]) // false
    isNaN([123]) // false
    isNaN(['123']) // false

    2.7.2使用isNaN之前,最好判断一下数据类型。

    function myIsNaN(value) {
      return typeof value === 'number' && isNaN(value);
    }

    2.7.3判断NaN更可靠的方法是,利用NaN是JavaScript之中唯一不等于自身的值这个特点,进行判断。

    function myIsNaN(value) {
      return value !== value;
    }


    3.Infinity
    3.1定义:特殊数值 number类型,不独立成数据类型;
    3.2表示无穷
    3.3场景:
    *正的太大
    *负的太小
    *非0数值除以0,得Infinity
    注意:0/0是NaN

    3.4正负之分:
    +Infinity表示正无穷 -Infinity表示负无穷

    3.5Infinity大于一切数,-Infinity小于一切  不考虑NaN
    3.6Infinity与NaN比较,怎么比都返回false;
    3.7
    1/-0   -Infinity
    -1/-0    Infinity
    -1/0     -Infinity
    1/0     Infinity

    3.8正负向溢出,被零除,js都不报错,说明单纯数学运算几乎没有可能抛出错误;

    3.9Infinity的四则运算符合无穷的运算规则;【这条不严谨,并非完全符合】
    3.10  0*Infinity//NaN 【居然不是0!  】
    3.11 null与Infinity计算  null转0 等同于与0计算
    3.12 undefined与Infinity计算全部返回NaN
    3.13Infinity加上或乘以Infinity,返回的还是Infinity。

    Infinity + Infinity // Infinity
    Infinity * Infinity // Infinity

    Infinity减去或除以Infinity,得到NaN。

    Infinity - Infinity // NaN
    Infinity / Infinity // NaN


    3.14isFinite函数
    isFinite函数返回一个boolean
    检查是不是一个正常的数值,或者能否转化为正常数值,遇到NaN,Infinity返回false;
    isFinite(Infinity) // false
    isFinite(-1) // true
    isFinite(true) // true
    isFinite(NaN) // false

    七、与数值相关的全局方法
    1.parseInt()
    1.1 字符串转整数
    1.2 转出来的数会有向下取整的效果:原因是认不出小数点。
    1.3要求参数是字符串。
    1.4相关问题:
    1.4.1 字符串头部带空格无影响;【中间、尾部空格未知】
    1.4.2 遇到不能转为数字的字符,返回已经转好的;
    1.4.3 参数不是字符串,先转字符再转数字,这会导致一些令人意外的结果。

    parseInt(0x11, 36) // 43
    // 等同于
    parseInt(String(0x11), 36)
    parseInt('17', 36)

    1.4.4 字符串的第一个字符不能转化为数字的情况,返回NaN,但是不包括"-123"这样后面跟着数的正负号
    1.4.5 parseInt返回值两种可能:  十进制数 NaN
    1.4.6 对于那些会自动转化科学技术的情况,parseInt会将科学技术的表示方法视为字符串,最终导致奇怪结果出现。

    parseInt(0.0000008) //等同于parseInt('8e-')//8

    1.4.7 涉及进制转换

    *parseInt('0x10')字符串是带前导的数,parseInt会按照相应的进制解析(命中字符串前导后,会用十六进制解读字符串,为十六进制数,然后转成十进制数返回)
    *parseInt('1000',10)第二参默认是十,以十进制解析字符串,除非命中字符串先导或者手动修改这个第二参
    *第二个参数是0、undefined和null,则直接忽略。

    parseInt('10', 37) // NaN
    parseInt('10', 1) // NaN
    parseInt('10', 0) // 10
    parseInt('10', null) // 10
    parseInt('10', undefined) // 10

    *第二参是整数,这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN。
    *第二参不是数,或者是小数会自动转成整数,该作死用法此处不研究

    *指定了解析进制,字符串中出现无意义字符,从最高位返回可转数,最高位如果都转不了,返回NaN
    *指定第二参,就按照第二参的进制解析字符串;
    未指定第二参,字符串中有先导被命中,按照先导的进制解析;
    以上两个都没有,默认十进制解析;
    parseInt('011',2) 会以二进制处理字符串"011" //得到结果是十进制3
    parseInt('011')  不同浏览器不一样,有的能认出先导0,有的认不出来认为是10进制;

    *对于八进制的前缀0,加上第一参非字符串转字符串,两个问题在一起就更纠结了
    parseInt(011, 2) // NaN
    // 等同于
    parseInt(String(011), 2)
    由于String(011)这一步转为"9",具体过程是识别出其中的先导,以八进制解析数字为十进制数字9,完了转为字符串。

    *ES5不再允许将带有前缀0的数字视为八进制数,而是要求忽略这个0。但是,为了保证兼容性,大部分浏览器并没有部署这一条规定。

    parseFloat认不出前导
    parseInt parseFloat前后空格过滤,中间空格算识别不出的字符
    parseFloat不认前导,没有第二参数来做进制转换功能

    parseInt有设定参数控制解析进制的功能,toString()有指定参数控制输出进制的功能;


    2.parseFloat方法()
    2.1含义:parseFloat方法用于将一个字符串转为浮点数;
    2.2遇到不能转为浮点数的字符,则返回已转好的;
    2.3自动过滤前导空格,参数字符串首位空格忽略
    2.4字符串第一个字符都不能转直接返回NaN
    2.5参数不是字符串,先转字符串(自动),再转浮点数
    2.6字符串书写符合科学计数法,能被命中(能认得出来),返回的数值会做相应转换。
    parseFloat('314e-2') //3.14
    2.7 parseFloat解析过程中遇到首位(+、-),数字0-9,小数点,科学计数法中的指数标记(e或者E)以外字符,就认不出来了

    2.8parseFloat()方法对比Number函数。
    parseFloat(true)  // NaN
    Number(true) // 1

    parseFloat(null) // NaN
    Number(null) // 0

    parseFloat('') // NaN
    Number('') // 0

    parseFloat('123.45#') // 123.45
    Number('123.45#') // NaN



  • 相关阅读:
    redis
    sqlalchemy ORM
    元类的理解
    python连接mysql
    ffmpeg去水印
    ffmpeg给视频加文字水印
    yt-seo-checklist
    ffmpeg下载直播流
    ffmpeg拼接mp4视频
    ffmpeg截取视频
  • 原文地址:https://www.cnblogs.com/xsfx/p/7112736.html
Copyright © 2020-2023  润新知