- ES6分别用前缀
0b(或0B)和0o(或0O)表示二进制和八进制数值。
0b111110111 // 503
0o767 // 503
如果要将0b和0o前缀的字符串数值转为十进制,要使用Number方法。
Number('0b111') // 7
Number('0o10') // 8
- ES2021中,较长的数值允许使用
_作为分隔符,该数值分隔符不指定间隔的位数;小数和科学计数法也能使用数值分隔符。
1_000_000_000_000 === 10 ** 12 // true
12_300 === 123_00 // true
0.000_001
1e10_000
数值分隔符的注意点:
- 不能放在数值的最前面或最后面
- 不能两个或两个以上的分隔符连在一起
- 小数点前后不能有分隔符
- 科学计数法里表示指数的
e或E前后不能有分隔符
下面三个函数不支持数值分隔符。
Number('123_456') // NaN
parseInt('123_456') // 123
parseFloat('123_456') // 123
Number.isFinite()用来检查一个数值是否为有限的。如果参数类型不是数值,一律返回false。
Number.isFinite(14) // true
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite('foo') // false
Number.isFinite(true) // false
Number.isNaN()用来检查一个值是否为NaN。如果参数类型不是NaN,一律返回false。
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.parseInt()和Number.parseFloat()是移植到Number对象上的parseInt()和parseFloat()。
Number.parseInt === parseInt // true
Number.parseFloat === parseFloat // true
Number.isInteger()用来判断一个数值是否为整数。如果参数不是数值,则返回false。在JavaScript内部,整数和浮点数采用的是同样的储存方法,所以25和25.0被视为同一个值。
Number.isInteger(25.1) // false
Number.isInteger(25) // true
Number.isInteger(25.0) // true
由于JavaScript的数值存储为64位双精度格式,数值精度最多可以达到53个二进制位。如果数值精度超过这个限度,第54位及后面的位就会被舍弃,在这种情况下,Number.isInteger()可能会误判。
Number.isInteger(3.000000000000000002) / true
如果一个数值的绝对值小于5E-324,会被自动转为0,这时Number.isInteger()也会误判。
Number.isInteger(5E-324) // false
Number.isInteger(5E-325) // true
6.Number.EPSILON表示1与大于1的最小浮点数之间的差。对于64位浮点数来说,大于1的最小浮点数相当于二进制的1.00..001(小数点后有连续51个零),这个值减去1后就等于2的-52次方。
Number.EPSILON === Math.pow(2,-52) // true
Number.EPSILON实质是一个可以接受的最小误差范围。比如误差范围设为2的-50次方(即Number.EPSILON * Math.pow(2,2)),如果两个浮点数的差小于这个误差范围,我们就认为这两个浮点数相等。
0.1 + 0.2 === 0.3 // false
0.1 + 0.2 - 0.3 // 5.551115123125783e-17
5.551115123125783e-17 < Number.EPSILON * Math.pow(2,2) // true
- 常量
Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER表示安全整数范围的上下限。
Number.MAX_SAFE_INTEGER // 9007199254740991
Number.MIN_SAFE_INTEGER // -9007199254740991
Number.isSafeInteger()用来判断一个整数是否落在安全整数范围之内。
Number.isSafeInteger('a') // false
Number.isSafeInteger('9007199254740990') // true
Number.isSafeInteger('1.2') // false
Number.isSafeInteger()相当于以下函数:
Number.isSafeInteger = function (n) {
return (typeof n === 'number' && Math.round(n) === n && Number.Min_SAFE_INTEGER <= n && Number.MAX_SAFE_INTEGER >= n)
}
使用这个函数验证运算结果是否落在安全整数的范围内,同时也要验证参与运算的每个值。
Number.isSafeInteger(9007199254740993) // false
Number.isSafeInteger(990) // true
Number.isSafeInteger(9007199254740993-990) // true
9007199254740993-990 // 返回9007199254740002,实际为9007199254740003
Math对象的扩展
Math.trunc()
Math.trunc去除一个数的小数部分,返回整数部分。
Math.trunc(4.1) // 4
对于非数值,Math.trunc使用Number方法先将其转化为数值。
Math.trunc('123.456') // 123
Math.trunc(null) // 0
Math.trunc(true) // 1
对于空值和无法截取整数的值,返回NaN。
Math.trunc('foo') // NaN
Math.trunc() // NaN
Marh.sign()
Math.sign用于判断一个数是正数、负数、还是零。对于非数值,会先将其转换为数值。
Math.sign(2) // +1 参数为正数 返回+1
Math.sign(-2) // -1 参数为负数 返回=1
Math.sign(0) // 0 参数为0 返回0
Math.sign(-0) // -0 参数为-0 返回-0
Math.sign(NaN) // NaN 其他值返回NaN
Math.cbrt()
Math.cbrt用于计算一个数的立方根。对于非数值,会先将其转换为数值。
Math.cbrt(-1) // -1
Math.cbrt(2) // 1.2599210498948732
Math.clz32()
Math.clz32()将参数转为32位无符号整数的形式,然后返回这个32位值里面有多少个前导0.
// 10的二进制形式是0b1010,1010只占了4位,所以32位之中有28个前导0
Math.clz(10) // 28
对于小数,Math.clz32()只考虑整数部分。
Math.clz32(3.2) // 30
对于空值或其他类型的值,Math.clz32()先将其转为数值再进行计算。
Math.imul()
Math.imul方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。
Math.imul(2, 4) // 8
如果只考虑最后32位,大多数情况下,Math.imul(a, b)与a * b的结果是相同的,即该方法等同于(a * b)|0。
Math.fround()
Math.fround返回一个数的32位单精度浮点数形式。对于32位单精度格式来说,数值精度是24个二进制位,所以对于-224
至224之间的整数(不含两个端点),返回结果与参数本身一致。
Math.fround(2 ** 24 - 1) //16777215
当参数绝对值大于224,返回的结果会丢失精度。
Math.fround(2 ** 24) //16777216
Math.fround(2 ** 24 + 1) //16777216
Math.hypot()
Math.hypot返回所有参数的平方和(即a2+b2)的平方根。
Math.hypot(3, 4) // 5
Math.hypot() // 0
Math.hypot(3, '4') // 5
Math.hypot(NaN) // NaN
Math.hypot(-3) // 3
如果参数不是数值,Math.hypot会先将其转为数值。只要有一个参数无法转为数值,就会返回NaN。
对数方法
Math.expm1()返回ex-1,即Math.exp(x)-1。
Math.expm1(0) // 0
Math.expm1(1) // 1.718281828459045
对于没有部署这个方法的环境,可以用以下代码模拟。
Math.expm1 = Math.expm1 || function(x) {
return Math.exp(x) - 1;
}
Math.log1p(x)返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN。
Math.log1p(0) // 0
Math.log10(x)返回以10为底的x的对数。如果x小于0,则返回NaN。
Math.log10(1) // 0
Math.log10(10) // 1
Math.log2(x)返回以2为底的x的对数。如果x小于0,则返回NaN。
Math.log2(2) // 1
BigInt数据类型
JavaScript所有数字都保存成64位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到53个二进制位(相当于16个十进制位),大于这个范围的整数无法被JavaS精确表示。二是JavaScript无法表示大于或等于2的1024次方的数值,会返回Infinity。
BigInt(大整数)是ECMAScript的第八种数据类型。它只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。BigInt类型的数据必须添加后缀n。
const a = 2172141653n;
const b = 15346349309n;
a * b // 33334444555566667777n
const x = 2172141653;
const y = 15346349309;
x * y // 33334444555566670000
BigInt函数
BigInt函数可以将其他类型的值转为BigInt。当没有参数或者参数不能正常转为数值时都会报错。
BigInt(1234) // 1234n
BigInt(false) // 0n
BigInt('123') // 123n
// 参数为小数时也会报错
BigInt(1.5) // RangeError
取反运算符(!)可以将BigInt转为布尔值。
!0n // true