定义
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()函数解析对象时,步骤如下:
- 先调用对象的valueOf()方法,如果返回原始类型值,就对返回值调用Number()函数;如果返回非原始类型值,就接着调用toString()方法。
- 如果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"