JS中只有一种数值类型,即number。不管是整数还是小数都属于number类型,事实上JS并不区分小数和整数。

<div>
<script type="text/javascript">
var num1 = 40.00;
var num2 = 40;
alert(num1 === num2);//alert true
</script>
</div>

我们对40.00和40使用运算符===进行比较发现返回true,也就是说二者完全相同。和绝大多数流行的脚本语言一样,JS语言的number类型基于IEEE 754标准实现。IEEE 754定义了如何在计算机中存储和表示浮点数,关于它的细节,有兴趣的朋友可以参考维基百科对IEEE 754的说明。

IEEE 754:http://en.wikipedia.org/wiki/IEEE_754-1985

下面来看一下数值类型的一些不常见的书写方式。

    <script type="text/javascript">
var num1 = 0.42;
var num2 = .42;
alert(num1 === num2);
var num3 = 42.0;
var num4 = 42.;
alert(num3 === num4);
</script>

小数点前面为0时,可以省略,.42也是合法的数字。小数点后面全部为0时,也可以省略小数点后面的部分。.42和42.虽然是合法的数字,但是为了代码的可读性,我们通常不会这样写。

再来看看JS数值比较中,比较容易让人产生困惑的问题:

    <script type="text/javascript">
alert((0.1 + 0.2) === 0.3); //false
</script>

我们使用(0.1 + 0.2) === 0.3,按照正常的编程逻辑,该表达式应该返回true才对,但这里偏偏返回的是false。这是什么原因呢?

首先需要明确的一点是,这并不是JavaScript语言的问题,所有使用IEEE 754标准实现浮点数的语言都要面对这个问题。下面笔者就来解释一下这个原因,大家都知道任何两个数(例如0.1和0.2)之间都有无数多个数,每一个数都在计算机中表示出来是不可能的。对于一个浮点数运算,计算机并不能精准的计算出它的结果,而是尽可能的接近它。也就是说(0.1 + 0.2)的计算结果并不是精确的等于0.3,可能是0.30000000000000004,所以二者也就不可能相等。针对这种情况我们通常会这样处理,如果两个浮点数之差的绝对值小于某一个范围,我们就认为这两个浮点数相等。

有了这些理论基础,我们可以通过自定义函数解决浮点数比较问题,代码如下:

       if (!Number.EPSILON) {
Number.EPSILON = Math.pow(2,-52);
}
function numbersCloseEnoughToEqual(n1,n2) {
return Math.abs( n1 - n2 ) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
alert( numbersCloseEnoughToEqual( a, b ));//true

接着介绍一下number类型中几个特殊的值:

1.NaN,它表示该值不是一个数值,是不是很奇怪,看下面的代码:

    <script type="text/javascript">
var num = 1/"abc";
alert(num);//NaN
alert(typeof num);//number
alert(num === NaN);//false
alert(isNaN(num));//true
</script>

我们用数字除以一个字符串,结果为NaN,它表明该计算结果不是一个数值。使用typeof操作符查看类型,确实是number类型。接下来”奇怪”的事情又来了,我们用===运算符和NaN进行比较,发现结果又为false。这个问题ECMAScript规范中有提到过,NaN不等于任何一个NaN,我们可以使用JS内置函数isNaN来判断一个值是否是NaN。

2.Infinity与-Infinity,Infinity表示正无穷大,-Infinity表示负无穷大。

    <script type="text/javascript">
var num1 = 100/0;
var num2 = -100/0;
alert(num1);//Infinity
alert(num2);//-Infinity
alert(typeof num1);//number
alert(typeof num2);//number
alert(num1 + num2);//NaN
alert(num1 + num1);//Infinity
alert(num2 + num2);//-Infinity
</script>

大多数语言中,一个数与0相乘都会抛出运行时异常,例如Java中会抛出java.lang.ArithmeticException异常,但是JavaScript中则不会,正数与零相除的结果为正无穷Infinity,负数与零相除的结果为-Infinity,它们两个都是number类型的值,Infinity与-Infinity相加结果为NaN,两个Infinity相加结果还是Infinity,两个-Infinity相加也还是-Infinity。相减、相乘和相除的情况读者可以自己写代码测试。

演示代码地址:https://github.com/rongbo-j/you-dont-know-js

你不知道的JavaScript(四)数值的更多相关文章

  1. JavaScript四种数值取整方法

    一.Math.trunc() 1.定义 Math.trunc()方法去除数字的小数部分,保留整数部分. 2.语法 Math.trunc(value) 3.示例 console.log(Math.tru ...

  2. 读书笔记-你不知道的JavaScript(上)

    本文首发在我的个人博客:http://muyunyun.cn/ <你不知道的JavaScript>系列丛书给出了很多颠覆以往对JavaScript认知的点, 读完上卷,受益匪浅,于是对其精 ...

  3. 《你不知道的 JavaScript 上卷》 学习笔记

    第一部分: 作用域和闭包 一.作用域 1. 作用域:存储变量并且查找变量的规则 2. 源代码在执行之前(编译)会经历三个步骤: 分词/此法分析:将代码字符串分解成有意义的代码块(词法单元) 解析/语法 ...

  4. 《你不知道的JavaScript》整理(二)——this

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,这次研究了一下“this”. 当一个函数被调用时,会创建一个活动记录(执行上下文). 这个记录会包含函 ...

  5. 《你不知道的JavaScript》整理(一)——作用域、提升与闭包

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,里面分析了很多基础性的概念. 可以更全面深入的理解JavaScript深层面的知识点. 一.函数作用域 ...

  6. 从头开始学JavaScript (四)——操作符

    原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...

  7. JavaScript中的this(你不知道的JavaScript)

    JavaScript中的this,刚接触JavaScript时大家都在大肆渲染说其多么多么的灵巧重要,然而自己并不关心:随着自己对JavaScript一步步深入了解,突然恍然大悟,原来它真的很重要!所 ...

  8. 读《你不知道的JavaScript(上卷)》后感-浅谈JavaScript作用域(一)

    原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们,也入手看看这 ...

  9. JavaScript词法作用域—你不知道的JavaScript上卷读书笔记(一)

    前段时间在每天往返的地铁上抽空将 <你不知道的JavaScript(上卷)>读了一遍,这本书很多部分写的很是精妙,对于接触前端时间不太久的人来说,就好像是叩开了JavaScript的另一扇 ...

  10. 【你不知道的javaScript 上卷 笔记3】javaScript中的声明提升表现

    console.log( a ); var a = 2; 执行输出undefined a = 2; var a; console.log( a ); 执行输出2 说明:javaScript 运行时在编 ...

随机推荐

  1. BZOJ 1369 树形DP

    思路: f[i][j] 表示节点i 染成j时 子树的最小权值 (我会猜这个j很小 你打我吖~) 随便DP一发就好了 (证明我也不会) //By SiriusRen #include <cstdi ...

  2. stackoverflow 加载特慢解决方案,配置 hosts 屏蔽速度慢的第三方 API

    127.0.0.1 ajax.googleapis.com www.googletagservices.com www.gravatar.com 127.0.0.1 securepubads.g.do ...

  3. 使用BigDecimal完成小数点后的精确位数的四舍五入

    package com.ryan; import java.math.BigDecimal; class MyMath { public static double round(double num ...

  4. php语法学习:轻松看懂PHP语言

    基础语法 开头结尾 PHP脚本以 "<?php " 开头以 "?>" 结尾 <!DOCTYPE html> <html>&l ...

  5. 如何巧妙使用ZBrush中的Image Plane插件

    ZBrush®插件Image Plane提供了一种简单的方法加载图像到ZBrush中,以在添加纹理过程中进行使用,比如使用ZProject笔刷多边形着色,以及利用参考图建模等. ZBrush 中文版下 ...

  6. 路飞学城Python-Day19

    [23.绑定方法与非绑定方法介绍] 再类的内部的定义的函数分为两大类: 1.绑定方法: 绑定到对象的方法:直接用def做的函数属性,类内部定义的函数,如果没有绑定装饰器,就是给对象使用的函数,绑定给谁 ...

  7. AIM Tech Round 5 1028cf(A-E)

    AIM Tech Round 5 (codeforces上题目编号是1028)(A-E) ---完全被这次比赛打击,自己真的很渣--- 战况 依旧3题选手 被构造题坑得好惨 稍稍涨了rating,希望 ...

  8. 树莓派搭建 Google TV

    出处:http://my.oschina.net/funnky/blog/142067 树莓派搭建 Google TV 目录:[ - ] Google TV是啥玩意 ? 搭建我们自己的Google T ...

  9. [poj 2976] Dropping tests (分数规划 二分)

    原题: 传送门 题意: 给出n个a和b,让选出n-k个使得(sigma a[i])/(sigma b[i])最大 直接用分数规划.. code: //By Menteur_Hxy #include & ...

  10. HBase入门操作 常用命令和增删改查的简单应用操作

    这里启动关闭Hadoop和HBase的顺序一定是: 启动Hadoop—>启动HBase—>关闭HBase—>关闭Hadoop ssh localhost 开启hadoopcd /us ...