二进制和八进制的表示方法
从ES5开始,严格模式下就不允许八进制使用前缀0表示
ES6直接明确了这一点,不允许八进制使用前缀0表示,要使用前缀0o表示。
ES6的二进制八进制的新写法,二进制使用前缀0b(或0B),八进制使用前缀0o(或0O):
例:
二进制: 0b111110111===503 //true
八进制: 0o767===503 //true
如果要将0b和0o前缀的字符串数值转换成十进制,要使用Number方法:
例:
Number('0b111') //7
Number('0o10') //8
介绍一下Number.isFinite()、Number.isNaN()
ES6在Number对象上新提供了Number.isFinite()、Number.isNaN()两个方法。
Number.isFinite()用来检查一个数值是否为有限的(finite)。
Number.isNaN()用来检查一个值是否为NaN。
这两个新方法与传统的全局方法isFinite()和isNaN()的区别在于传统方法先调用Number()将非数值转为数值,再判断,而新方法只对数值有效,对于非数值一律返回false。Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
注意全局方法与Number对象的方法的区别,如何使用仁者见仁智者见智啦~
对比新旧两种方法,例:
isFinite(25) //true
isFinite("25") //true
Number.isFinite(25) //true
Number.isFinite("25") //false
isNaN(NaN) //true
isNaN("NaN") //true
Number.isNaN(NaN) //true
Number.isNaN("NaN") //false
Number.isNaN(1) //false
介绍Number.parseInt()、Number.parseFloat()
ES6将全局方法parseInt()和parseFloat()移植到了Number对象上面,行为完全保持不变。
这样做的目的只是为了逐步减少全局性方法,使得语言逐步模块化。
Number.parseInt === parseInt //true
Number.parseFloat === parseFloat //true
介绍Number.isInteger()
Number.isInteger()用来判断一个值是否为整数。需要主要的是,在JavaScript内部,整数和浮点数是同样的储存方法,所以3和3.0被视为同一个值。
Number.isInteger(25) //true
Number.isInteger(25.0) //true
Number.isInteger(25.1) //false
Number.isInteger("15") //false
Number.isInteger(true) //false
介绍Number.EPSILON
ES6在Number对象上面新增一个极小的常量——Number.EPSILON
意义:引入一个这么小的常量,目的在于为浮点数计算设置一个误差范围,我们知道浮点数计算是不精确的。
Number.EPSILON //2.220446049250313e-16
Number.EPSILON.toFixed(20) //'0.00000000000000022204'
0.1+0.2 //0.30000000000000004
0.1+0.2-0.3 //5.551115123125783e-17
5.551115123125783e-17.toFixed(20) //'0.00000000000000005551'
如果这个误差小于Number.EPSILON,我们就认为得到了正确结果
因此,Number.EPSILON的实质是一个可以接受的误差范围。
介绍安全整数和Number.isSafeInteger()
JavaScript 能够准确表示的整数范围在(-2)^53到2^53之间(不含两个端点),超过这个范围就无法精确表示。
Math.pow(2,53) === Math.pow(2,53)+1 //true
上面的代码中,超出2的53次方 之后,一个数就不精确了。
ES6为此引入两个常量Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER分别表示这个范围的上下限。
Number.MAX_SAFE_INTEGER === Math.pow(2,53) - 1 //true
Number.MAX_SAFE_INTEGER === 9007199254740991 //true
Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER //true
Number.MIN_SAFE_INTEGER === -9007199254740991 //true
Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内。
实际运用这个函数时,需要注意验证运算结果是否落在安全整数的范围内,另外不要只验证运算结果,还要同时验证参与运算的每个值。
例一个反面教材:
Number.isSafeInteger(9007199254740993) //false
Number.isSafeInteger(990) //true
Number.isSafeInteger(9007199254740993 - 990) //true
9007199254740993 - 990 //返回结果9007199254740002 正确答案应该是9007199254740003
Math对象的扩展
ES6在Math对象上新增了17个与数学相关的方法。所有这些方法都是静态方法,只能在Math对象上调用。
Math.trunc()
Math.trunc()方法用于去除一个数的小数部分,返回整数部分。
对于非数值,Math.trunc内部使用Number方法将其先转为数值。
对与空值和无法截取整数的值返回NaN。
Math.sign()
Math.sign()方法用来判断一个数到底是正数,负数,还是零。
对于非数值,会先将其转换为数值。
返回值有5种情况:
- 参数为正数,返回+1;
- 参数为负数,返回-1;
- 参数为0,返回0;
- 参数为-0,返回-0;
- 其他值,返回NaN。
Math.cbrt()
Math.cbrt()方法用于计算一个数的立方根。
对于非数值,Math.cbrt方法内部也是先使用Number方法将其转换为数值。
Math.clz32()
JavaScript的整数使用32位二进制形式表示,Math.clz32()方法返回一个数的32位无符号整数形式有多少个前导0
clz32函数名来自“count leading zero bits in 32-bit binary representations of a number”的缩写
左移运算符(<<)与Math.clz32方法直接相关,可能有些难以理解,看看例子吧
Math.clz32(0) //32
Math.clz32(1) //31
Math.clz32(1<<1) //30
Math.clz32(1<<2) //29
Math.clz32(1<<29) //2
对于小数,Math.clz32方法只考虑整数部分。
Math.clz32(3.2) //30
Math.clz32(3.9) //30
对于空值或其他类型的值,Math.clz32方法会将它们先转为数值,然后再计算
Math.clz32() //32
Math.clz32(NaN) //32
Math.clz32(Infinity) //32
Math.clz32(null) //32
Math.clz32('foo') //32
Math.clz32([]) //32
Math.clz32({}) //32
Math.clz32(true) //31
Math.imul()
Math.imul()方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。
大部分情况下Math.imul(a,b)与a*b的结果相同,即该方法等同于(a*b)|0(超过32位的部分溢出)。
之所以需要部署这个方法,是因为JavaScript有精度限制,超过2的53次方的值无法精确表示。
对于很大的数的乘法,地位数值往往都是不精确的,Math.imul方法可以返回正确的低位数值。
如以下例子,Math.imul可以返回正确的值1
(0x7fffffff * 0x7fffffff) | 0 //0
Math.imul( 0x7fffffff , 0x7fffffff ) //1
Math.fround()
Math.fround()方法返回一个数的单精度浮点数形式
对于整数来说Math.fround()方法返回结果不会有任何不同,区别主要在于那些无法用64个二进制位精确表示的小数,这时Math.fround()方法会返回最接近这个小数的单精度浮点数。如Math.fround(1.337) //1.3370000123977661
Math.hypot()
Math.hypot()方法返回所有参数的平方和的平方根
如果参数不是数值,Math.hypot()方法会将其转换为数值。只要有一个参数无法转为数值,就会返回NaN。
例3的平方加上4的平方,等于5的平方:
Math.hypot(3,4); //5
Math.hypot(3,4,5); //7.0710678118654755 (可多参数)
Math.hypot(3,4,'5'); //7.0710678118654755
Math.hypot(-3); //3
Math.hypot(); //0
Math.hypot(3,4,'foo'); //NaN
对数方法
ES6新增4个对数相关方法
Math.expm1()
Math.expm1(x)返回e^x-1,即Math.exp( x ) - 1。
Math.expm1(0) //0
Math.expm1(1) //1.718281828459045
Math.expm1(-1) //-0.6321205588285577
Math.log1p()
Math.log1p(x)方法返回ln(1+x),即Math.log(1+x)。如果x小于-1,则返回NaN。
Math.log1p(1) //0.6931471805599453
Math.log1p(0) //0
Math.log1p(-1) //-Infinity
Math.log1p(-2) //NaN
Math.log10()
Math.log10(x)返回以10为底的x的对数。如果x小于0,则返回NaN。
Math.log10(2) //0.3010299956639812
Math.log10(1) //0
Math.log10(0) //-Infinity
Math.log10(-2) //NaN
Math.log10(100000) //5
Math.log2()
Math.log2(x)返回以2为底的x的对数。如果x小于0,则返回NaN。
Math.log2(2) //1
Math.log2(1) //0
Math.log2(0) //-Infinity
Math.log2(-2) //NaN
Math.log2(1024) //10
Math.log2(1 << 29) //29
双曲函数方法
ES6新增6个双曲函数方法
- Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)
- Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)
- Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)
- Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
- Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
- Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)
Math.signbit()
Math.signbit()用来判断一个值的正负,但是如果参数是-0,它便会返回-0.
该方法算法如下:
- 如果参数是NaN,返回false
- 如果参数是-0,返回true
- 如果参数是负值,返回true
- 其他情况返回false
指数运算符
ES6新增了一个指数运算符( ** )。
2 ** 2 //4
2 ** 3 //8
指数运算符可以与等号结合,形成一个新的赋值运算符( **= )。
let a = 1.5;
a **=2 ; //等同于a = a * a;
let b =4;
b **=3; //等同于b = b * b * b;
注意:在V8引擎种,指数运算符与Math.pow的实现不相同,对于特别大的运算结果两者有细微差异。
Math.pow(99,99) //3.697296376497263e+197
99 ** 99 //3.697296376497268e+197
上面的代码种,两个运算结果的最后一位有效数字是有差异的。
Integer数据类型
简介
JavaScript所有数字都保存成64位浮点数,这决定了整数的精确程度只能到53个二进制位。大于这个范围的整数,JavaScript是无法精确表示的,这使得JavaScript不适合进行科学和金融方面的精确计算。
为了与Number类型区别,Integer类型的数据必须使用后缀n来表示
比如 1n+2n //3n
二进制、八进制、十六进制的表示法都要加上后缀n
比如
0b1101n //二进制
0o777n //八进制
0xFFn //十六进制
对于Integer类型的数据,typeof运算符将返回integer。
运算
在数学运算方面Integer类型的+、-、*、**这四个二元运算符与Number类型无异。
除法运算 / 会舍去小数部分,返回一个整数
如 9n / 5n //1n
几乎所有的Number运算符都可以用在Integer种,但是有两个除外:不带符号的右移位运算符>>> 和一元的求正运算符+,这两种在使用时会报错。前者是因为>>>要求最高位补0,Integer无最高位。后者是因为一元运算符+在asm.js里面总是返回Number类型或报错。
Integer类型不能与Number类型进行混合运算。
1n+1 //报错
相等运算符( = = )会改变数据类型,也是不允许混合使用的。
0n == 0 //报错TypeError
0n == false //报错TypeError
精确相等运算符( === )不会改变数据类型,因此可以混合使用。
0n === 0 //fasle