开头

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系列-类型(数字)的更多相关文章

  1. 深入js系列-类型(隐式强制转换)

    隐式强制转换 在其可控的情况下,减少冗余,让代码更简洁,很多地方都进行了隐式转换,比如常见的三目表达式.if().for().while.逻辑运算符 || &&,适当通过语言机制,抽象 ...

  2. 【转载】JS Number类型数字位数及IEEE754标准

    JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...

  3. JS Number类型数字位数及IEEE754标准

    JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...

  4. 深入js系列-类型(显式强制转换)

    什么是显式 这里的显式和隐式是以普遍的标准来进行讨论的,你能看出来是怎么回事,那么它对你是"显式",相反你不知道的话,对你就是"隐式" 抽象操作 字符串.数字. ...

  5. 深入js系列-类型(对象)

    开篇 值的传递方式 1.值传递 表示传递过程中复制了值 2.引用传递 表示传递过程中传递的是值的引用 js的传递方式 值传递 看下面的例子 // 这里值传递很容易理解 var a = 1 var b ...

  6. 深入js系列-类型(null)

    首先null是表示什么状态呢 这个是需要和上篇的undefined做一个区分 undefined 从未赋值 非关键词(也就是可以定义为变量名或者赋值给它) null 曾经赋值.目前没值 关键词 typ ...

  7. 深入js系列-类型(开篇)

    思考 作为一个编程人员,你可能从来没仔细思考过,为什么这么多高级语言会有类型这东西. 实际上,类型有点类似生活中的类别,我们日常生活,早已经把这个概念理解到了,切肉和切水果会用不同的刀. 语言级别的类 ...

  8. js中的数字格式变成货币类型的格式

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  9. 【D3.V3.js系列教程】--(十二)坐标尺度

    [D3.V3.js系列教程]--(十二)坐标尺度 1.多种类型的缩放尺度 Quantitative Scales Linear Scales Identity Scales Power Scales ...

随机推荐

  1. scrapy Crawl_spider

    命令行输入:scrapy genspider --list 可以看到scrapy给我们提供的爬虫模板: basiccrawlcsvfeedxmlfeed 一般都是用默认模板生成的spider,如果需要 ...

  2. Django的学习——全局的static和templates的使用

    一.问题 首先我们在进行Django框架搭建的时候我们需要建立一个全局的变量,一是为了实现代码的复用,二是为了方便管理,如下图的样式 二.解决 1.修改setting里面的配置文件①templates ...

  3. react的标记渲染机制

    // ReactUpdates.js  - enqueueUpdate(component) function dirtyComponents.push(component); https://jue ...

  4. vb.net 多线程爬虫抓取免费代理IP

    Class Program Public Shared masterPorxyList As List(Of proxy) = New List(Of proxy)() Public Class pr ...

  5. .net core使用jwt自动续期

    小弟不C才,最近看了下网上的jwt方案,于是自己写了一个简单的jwt方案和大家分享下,希望大家给点意见! 假如有一个读书网站,可以不用登陆就访问,当需要自己写文章的时候就必须登录,并且登录之后如果一段 ...

  6. vscode+flutter+win10搭建问题记录

    1.下载安装vscode.flutter sdk.安装vscode相关插件.android sdk,这些网上有教程,比如https://blog.csdn.net/SVNzK/article/deta ...

  7. android版本对应表

    API Level 最初Android版本 Linux内核版本 首次发布日期 后续Android版本 28 9 Unknown 2018-07-02(Beta 3) - 27 8.1 4.10 201 ...

  8. Java自学-集合框架 与数组的区别

    Java集合框架与数组的区别 示例 1 : 使用数组的局限性 如果要存放多个对象,可以使用数组,但是数组有局限性 比如 声明长度是10的数组 不用的数组就浪费了 超过10的个数,又放不下 //Test ...

  9. 5G:为人工智能与智能制造赋能

    近几年,全球有两大科技领域越来越热:一个是人工智能,另一个是5G.两者都是能够改变时代.改变社会.改变经济的颠覆性技术.目前,我国已经发放了四张5G牌照,5G产业处在爆发前夜的阶段:人工智能方面,业界 ...

  10. MSSQL记录表字段数据变化的相关SQl

    在软件实施过程中,也许会有这样的问题: 表中数据出现非预期的结果,此时不确定是程序问题,哪个程序,存储过程,触发器.. 或还是人为修改的结果,此时可以用触发器对特定的表字段做跟踪监视,记录每次新增,修 ...