深入js系列-类型(数字)
开头
js数字没有明确区分浮点数和整数类型,统一用number类型表示。
number 基于IEEE 754标准实现 js采用的是双精度(64位二进制)
我们看一个基于IEEE 754标准实现都有会有的经典问题
0.1 + 0.2 === 0.3 //false
// 原因是 0.1 0.2 不精确,相加不等于0.3 而是一个类似0.30000000004 的值,所以条件判断结果为false
我们很容易修正这个错误,知道是因为偏差值出现问题,我们可以定义一个偏差值,在此偏差值内我们认为两者相等。对于js来说,2^-52比较合适。目前ES6为我们提供了这个偏差值
// Number.EPSILON ES6提供的比较偏差值
// polyfill
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;
numbersCloseEnoughToEqual( a, b ); // true
numbersCloseEnoughToEqual( 0.0000001, 0.0000002 ); // false
特殊值
比起其他语言,js提供了数字的很多特殊值,我们看一下它们出现的场合以及判别方式
1.NaN
不是数字的数字,表示数字运算和数字解析中的错误
,比如数字运算中操作数不为数字,或者值无法被解析为十进制或十六进制,看下面的例子
var a = 2 / "foo" //NaN
var b = parseInt("f") //NaN
判别
尝试一 、=
// 意料之外 NaN和自身不相等
NaN == NaN
NaN === NaN
尝试二 isNaN
// 全局isNaN函数
var a = 2 / "foo"
is NaN(a) // true
[ undefined, null, true, false, {}, "1" , "foo" ].forEach( e => {
console.log(e, isNaN(e))
})
// 结果 对于undefined、{} 、"foo"都返回了true,明显他们不是NaN
undefined true
null false
true false
false false
{} true
1 false
foo true
//我们需要加一层保险,目前这个方案已经被ES6实现为Number.isNaN
//polyfill
if(!Number.isNaN) {
Number.isNaN = function(n) {
return typeof n === "number" && isNaN(n)
//或者
return n!==n
}
}
2.无穷数 传统编译语言中 除以0 会抛出编译错误或者运行时错误,例如除以0,在js中,这个错误被定义为常量,无穷数 Infinity(Number.POSITIVE_INFINITY),还有在运算中结果溢出的情况也会出现Infinity
var a = 1 / 0; // Infinity(Number.POSITIVE_INFINITY)
var b = -1 / 0; // -Infinity(Number.NEGATIVE_INfiNITY)
var a = Number.MAX_VALUE; // 1.7976931348623157e+308
a + a; // Infinity
a + Math.pow( 2, 970 ); // Infinity
// 无穷除以无穷
Infinity / -Infinity //NaN
// 有穷正数除以Infinity
1 / Infinity // 0
// 有穷负数除以Infinity
-1 / Infinity // -0
3.零值(0、-0) -0 是一些数学运算中会出现
var a = 0 / -3; // -0
var b = 0 * -3; // -0
-0的转换
a.toString(); // "0"
a + ""; // "0"
String( a ); // "0"
// JSON也如此,很奇怪
JSON.stringify( a ); // "0"而不是"-0"
+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0
// 比较操作
var a = 0;
var b = 0 / -3;
a == b; // true
-0 == 0; // true
a === b; // true
-0 === 0; // true
0 > -0; // false
a > b; // false
区分0和-0
function isNegZero(n) {
n = Number(n)
return (n === 0) && (1 / n === -Infinity)
}
// 案例
isNegZero( -0 ); // true
isNegZero( 0 / -3 ); // true
isNegZero( 0 ); // false
对于特殊等式的统一处理(能够处理 NaN -0) Object.is()
var a = 2 / "foo";
var b = -3 * 0;
Object.is( a, NaN ); // true
Object.is( b, -0 ); // true
Object.is( b, 0 ); // false
//一个简单的polyfill
if (!Object.is) {
Object.is = function(v1, v2) {
// 判断是否是-0
if (v1 === 0 && v2 === 0) {
return 1 / v1 === 1 / v2;
}
// 判断是否是NaN
if (v1 !== v1) {
return v2 !== v2;
}
// 其他情况
return v1 === v2;
};
}
深入js系列-类型(数字)的更多相关文章
- 深入js系列-类型(隐式强制转换)
隐式强制转换 在其可控的情况下,减少冗余,让代码更简洁,很多地方都进行了隐式转换,比如常见的三目表达式.if().for().while.逻辑运算符 || &&,适当通过语言机制,抽象 ...
- 【转载】JS Number类型数字位数及IEEE754标准
JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...
- JS Number类型数字位数及IEEE754标准
JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...
- 深入js系列-类型(显式强制转换)
什么是显式 这里的显式和隐式是以普遍的标准来进行讨论的,你能看出来是怎么回事,那么它对你是"显式",相反你不知道的话,对你就是"隐式" 抽象操作 字符串.数字. ...
- 深入js系列-类型(对象)
开篇 值的传递方式 1.值传递 表示传递过程中复制了值 2.引用传递 表示传递过程中传递的是值的引用 js的传递方式 值传递 看下面的例子 // 这里值传递很容易理解 var a = 1 var b ...
- 深入js系列-类型(null)
首先null是表示什么状态呢 这个是需要和上篇的undefined做一个区分 undefined 从未赋值 非关键词(也就是可以定义为变量名或者赋值给它) null 曾经赋值.目前没值 关键词 typ ...
- 深入js系列-类型(开篇)
思考 作为一个编程人员,你可能从来没仔细思考过,为什么这么多高级语言会有类型这东西. 实际上,类型有点类似生活中的类别,我们日常生活,早已经把这个概念理解到了,切肉和切水果会用不同的刀. 语言级别的类 ...
- js中的数字格式变成货币类型的格式
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- 【D3.V3.js系列教程】--(十二)坐标尺度
[D3.V3.js系列教程]--(十二)坐标尺度 1.多种类型的缩放尺度 Quantitative Scales Linear Scales Identity Scales Power Scales ...
随机推荐
- 初识Go语言--(2)Hello World
新建hello.go文件,内容如下 package main import "fmt" func main() { //输出Hello World fmt.Println(&quo ...
- Excel技能提升
函数 字符串全半角之间的转换 ASC将全角英文字母转换为半角英文字母,其语法是ASC(text) WIDECHAR()将半角英文字母转换为全角英文字母,语法是=WIDECHAR(text) find( ...
- MP3文件信息修改
MP3文件信息 参考链接:https://www.jianshu.com/p/e368517ec7b9 总结: ID3V1在MP3文件后面;ID3V2在MP3文件前面;现在有些文件是V1的,有些文件是 ...
- NET 在一个数组中查找另一个数组所在起始位置(下标从0开始,未找到返回-1)
问题: 如果 search 在 dist 中顺序出现而不要求连续出现,那代码应该如何修改?如何计算这种匹配的可能性? 数组 search=[5,4,6],在数据 dist=[1,5,5,4,3,4,5 ...
- 初识Markdown
目录 一.基础语法 二.语法规则 1.标题 2.列表 3.文字格式 4.链接 5.图片 6.引用 7.水平分隔线 8.代码块 9.表格 10.文档目录 11.转义定义 写在前面 Markdown(简称 ...
- 【翻译】Tusdotnet中文文档(3)自定义功能和相关技术
自定义功能和相关技术 本篇按照如下结构翻译 自定义功能 自定义数据仓库 相关技术 架构和总体概念 自定义数据仓库 tusdotnet附带一个存储库TusDiskStore,它将文件保存在磁盘上的一个目 ...
- PIE SDK内存矢量数据的创建
1.功能简介 GIS将地理空间数据表示为矢量数据和栅格数据.矢量数据模型使用点.线和多边形来表示具有清晰空间位置和边界的空间要素,如控制点.河流和宗地等,每个要素被赋予一个ID,以便与其属性相关联.栅 ...
- elasticsearch原理学习
用es也差不多一年左右了,但是都是只会用,底层做了什么一窍不通,没有核心竞争力,循序渐进,一个一个攻破,理解的多了,读的多了,自然能力就上去了,es底层是基于lucene的,所以今天先从lucene下 ...
- Angular4项目运行时URL自动加#方法
import {HashLocationStrategy , LocationStrategy} from '@angular/common'; @NgModule({ declarations: ...
- 安装php源码包内的扩展
本地环境 PHP 7.0.4 (cli) (built: Mar 13 2016 21:50:22) ( NTS ) 安装 进入源码包中的ext文件夹中 [root@test etc]# cd /us ...