• js你不知的那些基础问题-数值


    1 整数和浮点数

    JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。容易造成混淆的是,

    某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算。

    由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。

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

     2 数值精度

     JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

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

       符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。

    JavaScript 提供的有效数字最长53二进制位

    由于2的53次方是一个16位的十进制数值,所以简单的法则就是,JavaScript 对15位的十进制数都可以精确处理。

    (-1)^符号位 * 1.xx...xx * 2^指数部分
    

    3 数值范围  

      位浮点数的指数部分的值最大为2047,分出一半表示负数,

      则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),

           超出这个范围的数无法表示

         如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,

      即 JavaScript 无法表示这么大的数,这时就会返回Infinity

    Math.pow(2, 1024) // Infinity
    

      如果一个数小于等于2的-1075次方(指数部分最小值-1023,再加上小数部分的52位),

      那么就会发生为“负向溢出”,即 JavaScript 无法表示这么小的数,这时会直接返回0。

    Math.pow(2, -1075) // 0
    

      以下两种情况,JavaScript 会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示。

       (1)小数点前的数字多于21位。

    1234567890123456789012
    // 1.2345678901234568e+21
    

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

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

    4 特殊数值

    4.1 正负零

      JavaScript 内部实际上存在2个0:一个是+0,一个是-0

      区别就是64位浮点数表示法的符号位不同。它们是等价的。  

       唯一有区别的场合是,+0-0当作分母,返回的值是不相等的

    (1 / +0) === (1 / -0) // false
    

    4.2 NaN  

       (1)含义

      NaN是 JavaScript 的特殊值,表示“非数字”(Not a Number),

      主要出现在将字符串解析成数字出错的场合。

      0除以0也会得到NaN

    0 / 0 // NaN
    

      需要注意的是,NaN不是独立的数据类型,而是一个特殊数值,

      它的数据类型依然属于Number,使用typeof运算符可以看得很清楚

    typeof NaN // 'number'
    

      (2)运算规则

       NaN不等于任何值,包括它本身。

    NaN === NaN // false
    

      数组的indexOf方法内部使用的是严格相等运算符,所以该方法对NaN不成立。

    [NaN].indexOf(NaN) // -1
    

      NaN在布尔运算时被当作false

    Boolean(NaN) // false
    

      NaN与任何数(包括它自己)的运算,得到的都是NaN

    NaN + 32 // NaN
    NaN - 32 // NaN
    NaN * 32 // NaN
    NaN / 32 // NaN
    

    4.3 Infinity

    (1)含义

    Infinity表示“无穷”,用来表示两种场景。

    一种是一个正的数值太大,或一个负的数值太小,无法表示;

    另一种是非0数值除以0,得到Infinity

    // 场景一
    Math.pow(2, 1024)
    // Infinity
    
    // 场景二
    0 / 0 // NaN
    1 / 0 // Infinity
    

      由于数值正向溢出(overflow)、负向溢出(underflow)和被0除,

      JavaScript 都不报错,所以单纯的数学运算几乎没有可能抛出错误。

      Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)。

    Infinity > 1000 // true
    -Infinity < -1000 // true
    

      InfinityNaN比较,总是返回false

    Infinity > NaN // false
    -Infinity > NaN // false
    
    Infinity < NaN // false
    -Infinity < NaN // false
    

      0乘以Infinity,返回NaN;0除以Infinity,返回0Infinity除以0,返回Infinity

    0 * Infinity // NaN
    0 / Infinity // 0
    Infinity / 0 // Infinity
    

      Infinity加上或乘以Infinity,返回的还是Infinity

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

      Infinity减去或除以Infinity,得到NaN

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

    5.与数值相关的全局方法

    5.1 parseInt()

       (1)基本用法

      如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN

    parseInt('abc') // NaN
    parseInt('.3') // NaN
    parseInt('') // NaN
    parseInt('+') // NaN
    parseInt('+1') // 1
    

      所以,parseInt的返回值只有两种可能,要么是一个十进制整数,要么是NaN

         对于那些会自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串,

      因此导致一些奇怪的结果。

    parseInt(1000000000000000000000.5) // 1
    // 等同于
    parseInt('1e+21') // 1
    
    parseInt(0.0000008) // 8
    // 等同于
    parseInt('8e-7') // 8
    

      (2)进制转换

     parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,

    返回该值对应的十进制数。默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制。

    parseInt('1000') // 1000
    // 等同于
    parseInt('1000', 10) // 1000
    

      如果第二个参数不是数值,会被自动转为一个整数。

      这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN

      如果第二个参数是0undefinednull,则直接忽略。

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

      前面说过,如果parseInt的第一个参数不是字符串,会被先转为字符串

      这会导致一些令人意外的结果。

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

      上面代码中,十六进制的0x11会被先转为十进制的17,再转为字符串。

      然后,再用36进制或二进制解读字符串17,最后返回结果431

    5.2 parseFloat()

      如果字符串符合科学计数法,则会进行相应的转换。

    parseFloat('314e-2') // 3.14
    parseFloat('0.0314E+2') // 3.14
    

      parseFloat方法会自动过滤字符串前导的空格。

    parseFloat('	v
    12.34
     ') // 12.34
    

      如果参数不是字符串,或者字符串的第一个字符不能转化为浮点数,则返回NaN

    parseFloat([]) // NaN
    parseFloat('FF2') // NaN
    parseFloat('') // NaN
    

      这些特点使得parseFloat的转换结果不同于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
    

     5.3 isNaN()

      isNaN方法可以用来判断一个值是否为NaN

    isNaN(NaN) // true
    isNaN(123) // false
    

      但是,isNaN只对数值有效,如果传入其他值,会被先转成数值。

      比如,传入字符串的时候,字符串会被先转成NaN,所以最后返回true,这一点要特别引起注意。

      也就是说,isNaNtrue的值,有可能不是NaN,而是一个字符串。

    isNaN('Hello') // true
    // 相当于
    isNaN(Number('Hello')) // true
    

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

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

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

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

    5.4 isFinite()

      isFinite方法返回一个布尔值,表示某个值是否为正常的数值。

    isFinite(Infinity) // false
    isFinite(-Infinity) // false
    isFinite(NaN) // false
    isFinite(undefined) // false
    isFinite(null) // true
    isFinite(-1) // true
    

      除了Infinity-InfinityNaNundefined这几个值会返回false

      isFinite对于其他的数值都会返回true

     

    文章内容转自 阮一峰老师 JavaScript教程 https://wangdoc.com/javascript/index.html

  • 相关阅读:
    ActionBar Fragment的一个sample activity; 及获取runningAppProcess及跳转
    优化后台推送的service,减少被杀死的几率
    64位win7安装ubunto最新14.04的过程,及出现的问题的解决
    一次非线上iowait高的情况的检查
    一个愚蠢的python逻辑语法错误
    Bellman-Ford算法解决单源最短路问题
    Floyd算法解决多源最短路径问题
    最短路问题Dijkstra算法
    最小生成树之Kruskal算法
    最优二叉搜索树
  • 原文地址:https://www.cnblogs.com/WernerWu/p/11299539.html
Copyright © 2020-2023  润新知