数值的两种类型
ES6引入了bigint
类型,所以现在的数值,其实有两种类型:number
和bigint
。
bigint
类型用Bigint
函数定义(不带new
),或者在数字后面加上字母n
。
let a = Bigint(1);
let b = 1n;
number
和bigint
有很多区别。
首先,number
可以表示浮点数,但是bigint
正如它的名字,大整数,所以只能是整数。
其次,它们的取值范围不同,number
的取值范围是从Number.MIN_VALUE
到Number.MAX_VAlUE
,bigint
可以是无限大。
而且,bigint
不能跟number
混合运算。
数值进制表示
除了我们常见的十进制,js中还可以用二进制、八进制、十六进制表示数值。
二进制以0b
开头。
let num = 0b111; // 十进制的 7
八进制以0
开头。
let num = 011; // 十进制的 9
十六进制以0x
开头。
let num = 0x11; // 十进制的 17
一个矛盾的数字
js里面有个数,叫NaN
。翻译过来就是Not a Number
,代表不是数字。
但是。
console.log(typeof NaN); // number
是数也不是数,是也不是?
当一个数和非数值的值运算时,或者一个非数字转成数字时,就可能会产生NaN
。
'abc' - 1; // NaN
parseInt('abc'); // NaN
Number('abc'); // NaN
可以用isNaN
或Number.isNaN
来判断值是不是NaN
。
数字的表示方式
可以使用_
来人性化的表示。
let num = 10_000_000;
用来表示千分位,是不是更加直观了。
可以使用字母e
,表示科学计数法。
let mn = 1e6; // 百万
let bn = 1e8; // 一亿
还有之前说的bigint
。
let num = 1n;
0.1 + 0.2 != 0.3 ?
不等于0.3
,等于啥呢?

为啥等于0.30000000000000004
?
这是因为js的浮点数采用的是ieee 754这个标准,它约定了计算机浮点数的表示方法。像Java、Python等其他编程语言大都遵照这个标准。
简单点说,0.1 + 0.2
无法精确表达是因为二进制的原因,二进制决定了它只能表示2的整数次幂的数,比如:
.
.
.
,
16
,
8
,
4
,
2
,
1
,
1
2
,
1
4
,
1
8
,
1
16
.
.
.
...,16,8,4,2,1,\frac {1} {2},\frac {1} {4} ,\frac {1} {8},\frac {1} {16} ...
...,16,8,4,2,1,21,41,81,161...
如果一个不能表示为多个2的整数次幂的和,那么它的精度可能会丢失,最终保存的可能是一个近似值。
因为0.1
和0.2
都无法用2的整数次幂表示,所以它们都是存储的近似值,所以最终它们的和并非严格等于0.3
。
可以用Number.EPSILON
避免这个中问题:
Math.abs(0.3 - (0.1 + 0.2)) <= Number.EPSILON
Number.EPSILON
是一个非常小的数,如果两个数的差的绝对值小于这个数,可以近似的认为它们是相等的。
+0和-0
js里面有+0
和-0
之分,这个跟数学里面0
零既不是正数也不是负数是矛盾的。
所以js规定+0
是严格等于-0
的。
零的正负号是会带入运算的,但是因为+0
和-0
是相等的,所以大多数情况并不会影响计算结果。但是在进行除法的时候要注意:
console.log(1 / 0); // Infinity
console.log(1 / -0); // -Infinity
如果0作为分母,且分子是个非0的数,那么+0
作为分母得到的是正无穷大,-0
作为分母得到的是负无穷大。