资讯专栏INFORMATION COLUMN

ES6精华:数值扩展

newtrek / 2796人阅读

摘要:基础极值采用标准的位双精度格式存储数值。如果数值的精度超过此限度,第位及后面的会被丢弃。数值的极值分为两种可表示的极值和可精确计算的极值浮点型不算。超过精度的数值可正确显示,但由其计算得出的结果可能不准确。整型数值安全区间。

ES6为数值增加了些常量和方法,使计算更为简便安全。本篇概括了这中的精华知识。

1 基础 1.1 极值

JS采用IEEE 754标准的64位双精度格式存储数值。
数值的精度最多可达到53个二进制位(1个隐藏位和52个有效位)。
如果数值的精度超过此限度,第54位及后面的会被丢弃。

数值的极值分为两种:可表示的极值和可精确计算的极值(浮点型不算)。
可表示的极值:[5e-324, 1.7976931348623157e+308]
可精确计算的极值:[1 - Math.pow(2, 53), Math.pow(2, 53) - 1]

超过精度的数值可正确显示,但由其计算得出的结果可能不准确。

let num = 9007199254741002;
console.log( num ); // 9007199254741002
console.log( num + 1 ); // 9007199254741004
console.log( num + 3 ); // 9007199254741004

let n1 = Math.pow(2, 53) - 1 + 1 + 1;
let n2 = Math.pow(2, 53) - 1 + 1 + 2;
console.log(n1 === n2); // true

对于整数,最多能精确显示16个十进制位,超过会被截断。
对于小数,最多能精确显示小数点后16个十进制位,超过会被截断。

超过的位数会被截断。

console.log( 3.000000000000001 === 3 ); // false
console.log( 3.0000000000000001 === 3 ); // true
console.log( 0.123456789123456891 ); // 0.1234567891234569
1.2 进制

二进制:0b1000B
八进制:0o1000O0100
十六进制:0x1000X100
注意,可忽略0100格式表八进制,因为严格模式下不允许使用。

进制间的转化
使用进制的完整格式,通过toString在不同进制间转化。

console.log( (10).toString(2) ); // 1010
console.log( (0b100).toString(8) ); // 4
console.log( ("0o100").toString(16) ); // 40

使用进制的值,通过parseInt将其它进制转换成十进制。

console.log( parseInt(100, 2) ); // 4
console.log( parseInt(100, 8) ); // 64
console.log( parseInt("100", 16) ); // 256

使用进制的完整格式,通过Number将其它进制转化成十进制。

console.log( Number(0b100) ); // 4
console.log( Number("0o100") ); // 64
console.log( Number("0x100") ); // 256
2 Number

完整的API列表:地址。
此模块的方法,不会默认转化期待为数值类型而实际不是的参数。

2.1 模块化

将全局方法isFinite() & isNaN(),放到了Number模块下。
两者唯一的差别是,全局中的方法会默认转化非数值参数,Number模块下的不会。

console.log( isNaN("NaN") ); // true
- 等价于
console.log( isNaN(Number("NaN")) );

只要不是 NaN ,则为 false 。更为严格严谨。
console.log( Number.isNaN("NaN") ); // false
2.2 整数

增加了一些常量和方法为安全计算服务。

isInteger()
判断一个数值是否为整数。非数直接为false
在JS中,整数和浮点数的储存方式是相同的,所以2525.0被视为同一个值。

console.log( Number.isInteger("25") ); // false
console.log( Number.isInteger(25.0) ); // true
console.log( Number.isInteger(3.0000000000000002) ); // true

isSafeInteger()
判断整型数值是否处于安全区间内。非整型即为false
整型数值安全区间:[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]
判断一个算式及其结果是否安全,需要验证它的各个项以及结果。

isTrusty(9007199254740993, 990, 9007199254740993 - 990); // 报错

function isTrusty(left, right, result) {
  if (Number.isSafeInteger(left)
    && Number.isSafeInteger(right)
    && Number.isSafeInteger(result)) {
    return result;
  }
  throw new RangeError("Operation cannot be trusted!");
}
2.3 误差

JS能识别的最小精度为Number.EPSILON,即Math.pow(2, -52)
如果误差小于此精度,就可以认为这点误差已经没有意义,即不存在误差了。
在实际项目中,可以设置计算的容错误差,以对比两个浮点数应不应该相同等等。

console.log( 0.1 + 0.2 ); // 0.30000000000000004
console.log( (0.1 + 0.2) === 0.3 ); // false
console.log( isEqualInErrorRange(0.1 + 0.2, 0.3) ); // true

function isEqualInErrorRange(left, right) {
  return Math.abs(left - right) < Number.EPSILON;
}

设定需要精确的位数,将浮点型转化成整型,来较为安全的计算浮点数。

console.log( countFloat(0.1, 0.2, "+", 14) ); // 0.3

function countFloat(a, b, sign, num) {
  let res;
  let times = Math.pow(10, num);
  let _a = Math.floor(a * times);
  let _b = Math.floor(b * times);
  
  switch (sign) {
    case "-":
      res = isTrusty(_a, _b, _a - _b);
      break;
    case "+":
      res = isTrusty(_a, _b, _a + _b);
      break;
    case "/":
      res = isTrusty(_a, _b, _a / _b);
      break;
    case "*":
      res = isTrusty(_a, _b, _a * _b);
      break;
  }
  
  return res / times;
}
3 Math

完整的API列表:地址。
此模块的方法,会默认调用Number()转化,期待为数值类型而实际不是的参数。
此模块新增了些,可以自行实现的简易方法,直接查手册会更有效,就不列举了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95692.html

相关文章

  • ES6精华:正则扩展

    摘要:本篇概括了中正则表达式新增部分的精华要点最好有的基础。标志使正则处于模式。关于的字符扩展知识,可查看这里。四字节字符处于模式下的正则,可以正确识别位四字节字符。 本篇概括了ES6中正则表达式新增部分的精华要点(最好有ES5的基础)。 1 u 标志 使正则处于Unicode模式。 关于ES6的字符扩展知识,可查看这里。 1.1 四字节字符 处于Unicode模式下的正则,可以正确识别3...

    paulli3 评论0 收藏0
  • ES6精华:字符串扩展

    摘要:四字节字符大幅增强了对字节位字符的支持。内部使用编码规则网页通常为。字符固定为字节,字节为位二进制,其码点小于。有些符号的码点大于,需字节表示,即常说的位字符。表示方法新增一种表示字符的方法。用将码点括起,使其可直接表示超过的值。 1 四字节字符 ES6大幅增强了对4字节(32位)字符的支持。 JS内部使用UTF-16编码规则(网页通常为UTF-8)。 1字符固定为2字节,1字节为...

    Jiavan 评论0 收藏0
  • Set & Map:新生的数据集合及其弱引用衍生

    摘要:前言新增了两种基本的原生数据集合和加上和现在共有四种,以及由两者衍生出的弱引用集合和。其本身是生成实例数据集合的构造函数,可以接受一个数组或具有接口的数据结构作为参数用来初始化。返回键值对的遍历器对象,键值对为键名键值。 前言 ES6新增了两种基本的原生数据集合:Set和Map(加上Array和Object现在共有四种),以及由两者衍生出的弱引用集合:WeakSet和WeakMap。从...

    AprilJ 评论0 收藏0
  • ES6精华:函数扩展

    摘要:在函数方面的扩展比较丰富也很实用,本篇概括了这中的精华知识。所以无法成为构造函数,不能使用操作符。参数将扩展运算符作用于参数,即为参数。声明式,直接为函数名。通过构造函数生成的,为。函数的属性,在其描述对象的属性上,为函数名。 ES6在函数方面的扩展比较丰富也很实用,本篇概括了这中的精华知识。 1 箭头函数 箭头函数是ES6中定义函数的新形式。 新形式不仅简化了定义方式,更为函数本身...

    lansheng228 评论0 收藏0
  • 细说JS数组

    摘要:数组元素的读写使用访问数组元素时,将索引转换为字符串,然后将其作为属性名一样使用。第一个参数应该在前只展开一层数组元素不变,返回注意,只拼接第一层结构。 此乃犀牛书(第七章 数组)读书笔记,又结合了ES6中数组的扩展部分做的知识梳理。精华部分就是手工绘制的两张数组总结图了。灵活运用数组的各种方法是基本功,是基本功,是基本功,重要的事情说三遍。好了,正文从下面开始~ 数组的基本概念 什么...

    starsfun 评论0 收藏0

发表评论

0条评论

newtrek

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<