ECMA Script 6_数值的扩展

1. 二进制 和 八进制 新的表示法

前缀 0b(或0B) 表示 二进制

前缀 0o(或 0O )表示 八进制

  • console.log(0b111110111 === 503);    // true
    console.log(0o767 === 503);    // true
  • 如果要将 0b 和 0o 前缀的字符串数值 转为十进制,要使用 Number() 方法

2. Number.isFinite()

检查一个数值是否为有限的(finite),即 不是 Infinity 返回 true

只对数值有效

如果参数类型不是数值,Number.isFinite一律返回false

  • Number.isFinite(15);    // true
    Number.isFinite(0.8);    // true
    Number.isFinite(NaN);    // false
    Number.isFinite(Infinity);    // false
    Number.isFinite(-Infinity);    // false
    Number.isFinite('foo');    // false
    Number.isFinite('15');    // false
    Number.isFinite(true);    // false

3. Number.isNaN()

检查一个值是否为 NaN

只对数值有效

  • Number.isNaN(NaN);    // true
    Number.isNaN(15);    // false
    Number.isNaN('15');    // false
    Number.isNaN(true);    // false
    Number.isNaN(9/NaN);    // true
    Number.isNaN('true' / 0);    // true
    Number.isNaN('true' / 'true');    // true

4. Number.parseInt() Number.parseFloat()

将 全局方法 移植到对象 上面,行为完全保持不变

是为了 逐步减少全局性方法,使得语言逐步模块化

  • Number.parseInt === parseInt    // true
    Number.parseFloat === parseFloat    // true

5. Number.isInteger()

判断一个数值是否为整数

  • 整数 和 浮点数 采用的是同样的储存方法,所以 25 和 25.0 被视为同一个值
  • Number.isInteger(25);    // true
    Number.isInteger(25.0);    // true
  • JavaScript 采用 IEEE 754 标准,数值存储为64位双精度格式,数值精度最多可以达到 53 个二进制位(1 个隐藏位与 52 个有效位)。
  • 如果数值的精度超过这个限度,第54位及后面的位就会被丢弃,这种情况下,Number.isInteger可能会误判。
  • Number.isInteger(3.0000000000000002);    // true

所以,如果对数据精度的要求较高不建议使用 Number.isInteger() 判断一个数值是否为整数

6. Number.EPSILON

ES6 在 Number 对象上面,新增 一个极小的常量 Number.EPSILON ,即 JavaScript 能够表示的最小精度。

误差如果小于这个值,就可以认为已经没有意义了,即不存在误差了

根据规格,它表示 1 与大于 1 的最小浮点数之间的差

  • 对于 64 位浮点数来说,大于 1 的最小浮点数相当于二进制的1.00..001,小数点后面有连续 51 个零。
  • 这个值减去 1 之后,就等于 2 的 -52 次方
  • 用来设置 “能够接受的误差范围

比如,误差范围设为 2 的-50 次方(即Number.EPSILON * Math.pow(2, 2)),

即如果两个浮点数的差小于这个值,我们就认为这两个浮点数相等

  • 5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2);    // true
  • 一个可以接受的最小误差范围
  • // 误差范围设为 2 的 -50 次方
    function
    withinErrorMargin (left, right) { return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2); };
    0.1 + 0.2 === 0.3 // false withinErrorMargin(0.1 + 0.2, 0.3); // true 1.1 + 1.3 === 2.4 // false withinErrorMargin(1.1 + 1.3, 2.4); // true

7. 安全整数 和 Number.isSafeInteger()

JavaScript 能够准确表示的整数范围在-2^532^53之间(不含两个端点),超过这个范围,无法精确表示这个值

  • Number.isSafeInteger()

判断一个整数是否落在 [-2^53, 2^53] 范围之内

  • Number.isSafeInteger('a');    // false
    Number.isSafeInteger(null);    // false
    Number.isSafeInteger(NaN);    // false
    Number.isSafeInteger(Infinity);    // false
    Number.isSafeInteger(-Infinity);    // false
    
    Number.isSafeInteger(3);    // true
    Number.isSafeInteger(1.2);    // false
    Number.isSafeInteger(9007199254740990);    // true
    Number.isSafeInteger(9007199254740992);    // false
    
    Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1);    // false
    Number.isSafeInteger(Number.MIN_SAFE_INTEGER);    // true
    Number.isSafeInteger(Number.MAX_SAFE_INTEGER); // true Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1); // false
  • 验证 整个运算 是否可靠
  • function trusty (left, right, result) {
        if (
            Number.isSafeInteger(left) &&
            Number.isSafeInteger(right) &&
            Number.isSafeInteger(result) ){
            return result;
        };
        throw new RangeError('Operation cannot be trusted!');
    };
    
    trusty(9007199254740993, 990, 9007199254740993 - 990);    // RangeError: Operation cannot be trusted!
    
    trusty(1, 2, 3);    // 3

Math 对象的扩展

Math.trunc()

去除一个数的小数部分,返回整数部分

对于非数值,Math.trunc() 内部使用 Number() 将其先转为数值

  • Math.trunc(4.1);    // 4
    Math.trunc(4.9);    // 4
    Math.trunc(-4.1);    // -4
    Math.trunc(-4.9);    // -4
    Math.trunc(-0.1234);    // -0
    
    Math.trunc('123.456');    // 123
    Math.trunc(true);    //1
    Math.trunc(false);    // 0
    Math.trunc(null);    // 0

Math.sign()

判断一个数到底是 正数、负数、还是 零 

对于非数值,会先将其转换为数值

  • 参数为正数, 返回+1;
    参数为负数, 返回-1;
    参数为 0, 返回0;
    参数为-0, 返回-0;
    其他值, 返回NaN
    Math.sign(-5);    // -1
    Math.sign(5);    // +1
    Math.sign(0);    // +0
    Math.sign(-0);    // -0
    Math.sign(NaN);    // NaN

Math.cbrt

用于计算一个数的立方

于非数值,Math.cbrt() 方法内部也是先使用 Number() 将其转为数值

  • Math.cbrt('8');    // 2

Math.clz32() 

返回一个数的 32 位无符号整数形式有多少个前导 0

JavaScript 中,整数使用 32 位二进制形式表示

”count leading zero bits in 32-bit binary representation of a number“(计算一个数的 32 位二进制形式的前导 0 的个数)的缩写

  • Math.clz32(0);    // 32
    Math.clz32(1);    // 31
    Math.clz32(1000);    // 22
    Math.clz32(0b01000000000000000000000000000000);    // 1
    Math.clz32(0b00100000000000000000000000000000);    // 2
  • 左移运算符(<<)与 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()

返回两个数以 32 位带符号整数形式相乘的结果,

返回的也是一个 32 位的带符号整数

  • Math.imul(2, 4);    // 8
    Math.imul(-1, 8);     // -8
    Math.imul(-2, -2);    // 4

Math.fround()

返回一个数的 32 位单精度浮点数形式

主要作用,是将64位双精度浮点数转为32位单精度浮点数。

如果小数的精度超过 24 个二进制位,返回值就会不同于原值,

否则返回值不变(即与64位双精度值一致)

  • 对于32位单精度格式来说,数值精度是24个二进制位(1 位隐藏位与 23 位有效位),所以对于 -224 至 224 之间的整数(不含两个端点),返回结果与参数本身一致
  • Math.fround(0);    // 0
    Math.fround(1);    // 1
    Math.fround(2 ** 24 - 1);    // 16777215
  • 如果参数的绝对值大于 2的24次方,返回的结果便开始丢失精度
  • Math.fround(2 ** 24);       // 16777216
    Math.fround(2 ** 24 + 1);     // 16777216

Math.hypot()

返回 所有参数的平方和 的平方根

  • Math.hypot(3, 4);    // 5
    Math.hypot(3, 4, 5);    // 7.0710678118654755
    Math.hypot();    // 0
    Math.hypot(NaN);    // NaN
    Math.hypot(3, 4, 'foo');    // NaN
    Math.hypot(3, 4, '5');    // 7.0710678118654755
    Math.hypot(-3);    // 3

新增的 4 个 对数方法

Math.expm1(x)

返回 e 的 x 次方 - 1,即 Math.exp(x) - 1

Math.log1p()

返回 1 + x 的自然对数,即 Math.log(1 + x)

如果 小于-1,返回 NaN

Math.log10()

返回以 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()

333

  • Math.log2(3);       // 1.584962500721156
    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

双曲函数方法

  • 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)

指数运算符

ES6 新增了一个指数运算符(**)

  • 2 ** 2    // 4
    2 ** 3    // 8
  • 右结合,而不是常见的左结合。

多个指数运算符连用时,是从最右边开始计算的

  • 2 ** 3 ** 2    // 相当于 2 ** (3 ** 2)
    // 512
  • 指数运算符可以与等号结合,形成一个新的赋值运算符(**=
  • let a = 1.5;
    a **= 2;    // 等同于 a = a * a;    2.25
    
    let b = 4;
    b **= 3;    // 等同于 b = b * b * b;   64
  • 注意: V8 引擎的 指数运算符 与 Math.pow() 的实现不相同,对于特别大的运算结果,两者会有细微的差异
  • Math.pow(99, 99)    // 3.697296376497263e+197
    
    99 ** 99    // 3.697296376497268e+197
    
    // 上面代码中,两个运算结果的最后一位有效数字是有差异的。

 

posted @ 2018-12-16 12:47  耶梦加德  阅读(203)  评论(0编辑  收藏  举报