定义

JavaScript采用IEEE 754格式来表示数字,所以不区分整数和浮点数,JS中的数字都是用浮点数表示的。由于浮点型数值占据的内存空间是整数型的两倍,所以JS会不失时机的把浮点数值转换成整数,比如说本身就是一个整数或者小数点后面没有任何有效数值,这个数值就会被当做整数来保存

1.0 === 1; // true

整数

JS有四种表示整数的字面量格式:十进制、二进制、八进制、十六进制。在进行算数运算时,所有二进制、八进制和十六进制都会转换成十进制数值。

说明: 当一个数字直接出现在JS程序中时,称作数字的字面量。当使用new操作符表示数值时,称作Number对象。

二进制:二进制前两位必须是0b,后面是0-1的字符序列。如果数值超出范围会报错。

八进制:八进制的第一位必须是0,后面是0-7数字序列。如果数值超出范围,前导0会被忽略,后面数值被当做十进制解析。(八进制字面量在严格模式下报错,部分JS引擎不支持,所以不建议使用)

十六进制:十六进制前两位必须是0x,后面是0-9,a-f的字符序列,字母不需区分大小。如果数值超出范围会报错。

0b101; // 5
012; // 10
09; // 9 
0xf; // 15

浮点数

浮点数是指数值中必须包含一个小数点,且小数点后面至少一位数字。浮点数只可用十进制表示。

由于JS采用IEEE 754格式表示数字,所以浮点数不是精确值,这是所有采用IEEE 754格式语言的通病,所以涉及到浮点数的比较和运算要格外小心。

0.1 + 0.2 === 0.3; // false
0.1 * 3 === 0.3; // false

科学计数法

对于特别大和特别小的数值,可以使用科学计数法e或E来表示,e后面跟着一个整数用来表示指数。

当数值小于1且小数点后有大于等于6个0时,JS会自动将数值转换为科学计数法。

当数值整数位大于等于22位时,JS会自动将数值转换为科学计数法。

0.0000003 // 3e-7
1234567890123456789012 //1.2345678901234568e+21
123456789012345678901 //123456789012345680000

数值精度

JS数字类型在内部表示为64位二进制浮点,表现形式如下:

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

综上,JS提供的数字最长为53个二进制位,所以绝对值小于2的53次方的整数都可以精确表示。换算成十进制,JS数字最高精度是16位(如果整数位是0,表示小数点后16位;如果整数部分不为0,表示整体保留16位)。

Math.pow(2, 53) // 9007199254740992
0.1234567890123456 // 0.1234567890123456 
1.234567890123456 // 1.234567890123456

Math.pow(2, 53) + 1 // 9007199254740992 超出精度,不再精确
90071992547409921 // 90071992547409920 超出精度,不再精确
1.2345678901234566 // 1.2345678901234567 超出精度,不再精确

数值范围

64位浮点数的指数部分长度是11个二进制位,所以指数最大是2047(2^11 - 1)。分出一半表示负数,JS的数值范围是2^1024 到 2^-1023.

JS中的最大值保存在Number.MAX_VALUE中,最小值保存在Number.MIN_VALUE中

如果超过最大值,JS会返回Infinity,称作正向溢出;如果比最小值还小,由于数值已经无限接近于0,所以会返回0,称作负向溢出。

当运算数和最值是在同一精度上时,才可以与最值发生运算

Number.MAX_VALUE + 1 // 1.7976931348623157e+308
Number.MAX_VALUE+1e292 // Infinity

特殊数值

JS中有九个特殊数值:Number.MAX_VALUE、Number.MIN_VALUE、Number.POSITIVE_INFINITY、Number.NEGATIVE_INFINITY、Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER、Number.NaN、+0、-0。

最值

Number.MAX_VALUE、Number.MIN_VALUE分别表示最大值和最小值

Infinity

Number.POSITIVE_INFINITY对应的是Infinity,代表正无穷;Number.NEGATIVE_INFINITY对应的是-Infinity,代表负无穷。可以通过isFinite()确定是否是有穷的。

Number.POSITIVE_INFINITY === Infinity // true
Number.NEGATIVE_INFINITY === -Infinity // true
isFinite(Infinity) // false
isFinite(1) // true

安全最值

Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER表示最大整数和最小整数

Number.MAX_SAFE_INTEGER === Math.pow(2, 53)-1 // true
Number.MIN_SAFE_INTEGER === -(Math.pow(2, 53)-1) // true

NaN

NaN表示非数字,它和任何值都不相等(包括自身),可以通过isNaN()判断一个值是不是NaN,它包含隐式类型转换函数Number()。

isNaN(10) //false
isNaN('10') //false
isNaN([]) // false
isNaN(null) // false

isNaN(NaN) //true
isNaN('Hello') //true
isNaN({}) // true
isNaN(undefined) // true

[]null调用Number()转型函数后返回0,而{}和·undefined调用Number()转型函数后返回NaN

扩展: ES6为Number类型新增了一个isNaN()静态方法,它不包函隐式类型转换,因此只有值是NaN是才返回true,其他值均返回false

正负零

在JS中,正负零是恒等的

-0 === +0;// true
0 === -0;// true
0 === +0;// true

数值转换

三个函数可以把非数值转换为数值:Number()、parseInt()、parseFloat()。

Number()

当Number()作为转型函数调用时,可以把任意类型的值转换成数值。

Number(11) // 11
Number(011) //  9
Number(0x11) //  17
Number(undefined) // NaN
Number(null) // 0
Number(true) // 1
Number(false) // 0

Number()解析字符串时,会把前置空格去掉,空字符串和空白字符都会转换成0.

Number()会自动把字符串形式的十进制数和十六进制数都转换为十进制,但是不识别八进制,会被当做十进制数处理。

其他情况字符串,转换成NaN

Number('   123') // 123
Number(' ') // 0

Number('11') // 11
Number('011') //  11
Number('0x11') //  17

Number('hello') // NaN

Number()函数解析对象时,步骤如下:

  1. 先调用对象的valueOf()方法,如果返回原始类型值,就对返回值调用Number()函数;如果返回非原始类型值,就接着调用toString()方法。
  2. 如果toString()方法返回原始类型值,就对返回值调用Number()函数;如果返回还是对象就返回NaN。
Number([1]) // 1
Number([1,2]) // NaN
Number({}) // NaN

parseInt()

parseInt()方法用于把字符串转换成整数,转换时会忽略前导空格,如果第一个字符非数字或非负号,结果返回NaN。如果是数字,继续向后解析直到遇到非数字字符。

parseInt('  10px') // 10
parseInt('  -10px') // -10
parseInt('10.5') // 10

parseInt()方法在解析各种进制的数值时均返回十进制数,但是解析八进制字符串时,会当做十进制处理输出。对于会自动转换成科学计数法的数值,会把科学计数法当做字符串处理。

parseInt(11) // 11
parseInt(011) // 9
parseInt(0x11) // 17

parseInt('11') // 11
parseInt('011') // 11
parseInt('0x11') // 17

parseInt(0.0000008) // 8
// 等价于
parseInt('8e-7')) // 8

parseInt()方法可以接收第二个参数(2到36之间),表示解析值的进制,默认是10表示十进制。

console.log(parseInt('11',2));//3
console.log(parseInt('11',8));//9
console.log(parseInt('11',10));//11
console.log(parseInt('11',16));//17

parseFloat()

parseFloat()方法用于把字符串转换成浮点数,解析时同样会忽略前导空格,从第一个数字开始解析直到遇到无效的浮点值结束。


parseFloat('20.30.3') // 20.3
parseFloat('-20.00元')  // -20

科学计数法表示的数字会自动进行转换,然后再求浮点值

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

parseFloat()可以识别不同进制的数字,但只能解析十进制字符串,八进制字符串会被当做十进制处理。

parseFloat(11) // 11
parseFloat(011) // 9
parseFloat(0x11) // 17

parseFloat('11') // 11
parseFloat('011') // 11
parseFloat('0x11') // 0

实例方法

Number()对象有六个实例方法:toString()、toLocaleString()、valueOf()这三种继承自Object对象;toFixed、toExponential()、toPrecision()这三种改变数值显示方式并转换为字符串形式

继承方法

valueOf()方法返回对象数字字面量

toString()方法将数字转换为字符串

toLocaleString()方法将数字转换为本地格式字符串

(123).valueOf() // 123
(123).toString() // '123'
(123).toLocaleString() // '123'

注意: 如果数字不加括号,后面的点会被当做小数点处理,所以会报错。可以使用两个点或者为数字加括号避免出错。

toString()方法接收一个参数,参数为2-36间的一个整数,表示输出的进制,默认是十进制。

(10).toString(2) // '1010'
(10).toString(8) // '12'
(10).toString(16) // 'a'

toFixed()

toFixed()方法接收一个参数(0-20之间的整数),表示保留小数的位数,返回四舍五入后数字的字符串形式。如果不传参参数相当于0


(100.234).toFixed(2) // '100.23'
(100.234).toFixed(0) // '100'
(100.234).toFixed() // '100'

toExponential()

toExponential()方法接收一个参数(0-20之间的整数),表示保留小数的位数,返回四舍五入后科学计数法的字符串形式。如果不参数会保留尽可能多的有效数字。

(100.234).toExponential(2) // "1.00e+2"
(100.234).toExponential(0) // "1e+2"
(100.234).toExponential() // "1.00234e+2"

toPrecision()

toPrecision()方法接收一个参数(1-21之间的整数),表示所有数字的位数,返回指定位数的字符串,它会自动调用toFixed()或toExponential()方法。如果不传参相当于调用toString()方法

(100.234).toPrecision(2) // "1.0e+2"
(100.234).toPrecision(3) // "100"
(100.234).toPrecision(0) // 报错
(100.234).toPrecision() // "100.234"