你不知道的JavaScript(四)数值
2015-05-17 20:46
225 查看
JS中只有一种数值类型,即number。不管是整数还是小数都属于number类型,事实上JS并不区分小数和整数。
我们对40.00和40使用运算符===进行比较发现返回true,也就是说二者完全相同。和绝大多数流行的脚本语言一样,JS语言的number类型基于IEEE 754标准实现。IEEE 754定义了如何在计算机中存储和表示浮点数,关于它的细节,有兴趣的朋友可以参考维基百科对IEEE 754的说明。
IEEE 754:http://en.wikipedia.org/wiki/IEEE_754-1985
下面来看一下数值类型的一些不常见的书写方式。
小数点前面为0时,可以省略,.42也是合法的数字。小数点后面全部为0时,也可以省略小数点后面的部分。.42和42.虽然是合法的数字,但是为了代码的可读性,我们通常不会这样写。
再来看看JS数值比较中,比较容易让人产生困惑的问题:
我们使用
首先需要明确的一点是,这并不是JavaScript语言的问题,所有使用IEEE 754标准实现浮点数的语言都要面对这个问题。下面笔者就来解释一下这个原因,大家都知道任何两个数(例如0.1和0.2)之间都有无数多个数,每一个数都在计算机中表示出来是不可能的。对于一个浮点数运算,计算机并不能精准的计算出它的结果,而是尽可能的接近它。也就是说
有了这些理论基础,我们可以通过自定义函数解决浮点数比较问题,代码如下:
接着介绍一下number类型中几个特殊的值:
1.NaN,它表示该值不是一个数值,是不是很奇怪,看下面的代码:
我们用数字除以一个字符串,结果为NaN,它表明该计算结果不是一个数值。使用typeof操作符查看类型,确实是number类型。接下来”奇怪”的事情又来了,我们用===运算符和NaN进行比较,发现结果又为false。这个问题ECMAScript规范中有提到过,NaN不等于任何一个NaN,我们可以使用JS内置函数isNaN来判断一个值是否是NaN。
2.Infinity与-Infinity,Infinity表示正无穷大,-Infinity表示负无穷大。
大多数语言中,一个数与0相乘都会抛出运行时异常,例如Java中会抛出
演示代码地址:https://github.com/rongbo-j/you-dont-know-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(四)数值
- 你不知道的JavaScript(四)数值
- 你不知道的JavaScript--Item15 prototype原型和原型链详解
- 你可能不知道的10个JavaScript小技巧
- 不知道的JavaScript
- [图解] 你不知道的 JavaScript - “this”
- javaScript中自定义sort中的比较函数,用于比较字符串长度,数值大小
- javascript 从定义到执行,你不知道的那些事
- JavaScript基础 使用unshift向 数组开头 追加数值 追加数组
- 【你不知道的JavaScript(上)读书笔记】第1章:作用域
- JavaScript中的this(你不知道的JavaScript)
- JavaScript中你所不知道的数组ArrayBuffer
- 你可能不知道的java、python、JavaScript以及jquary循环语句的区别
- 《你不知道的JavaScript(上卷)》笔记:关于this
- 你或许不知道的javascript细节
- JavaScript中的数值转换函数
- javascript你不知道的This
- Javascript 你不知道的几个内置类型
- java和javascript的交替使用计算(1+1)*3/2+1的数值
- javascript中如何将字符型数字转换为数值型(二)