安全整数和 Number.isSafeInteger()

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

  1. Math.pow(2, 53) // 9007199254740992
  2. 9007199254740992 // 9007199254740992
  3. 9007199254740993 // 9007199254740992
  4. Math.pow(2, 53) === Math.pow(2, 53) + 1
  5. // true

上面代码中,超出 2 的 53 次方之后,一个数就不精确了。

ES6 引入了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。

  1. Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1
  2. // true
  3. Number.MAX_SAFE_INTEGER === 9007199254740991
  4. // true
  5. Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER
  6. // true
  7. Number.MIN_SAFE_INTEGER === -9007199254740991
  8. // true

上面代码中,可以看到 JavaScript 能够精确表示的极限。

Number.isSafeInteger()则是用来判断一个整数是否落在这个范围之内。

  1. Number.isSafeInteger('a') // false
  2. Number.isSafeInteger(null) // false
  3. Number.isSafeInteger(NaN) // false
  4. Number.isSafeInteger(Infinity) // false
  5. Number.isSafeInteger(-Infinity) // false
  6. Number.isSafeInteger(3) // true
  7. Number.isSafeInteger(1.2) // false
  8. Number.isSafeInteger(9007199254740990) // true
  9. Number.isSafeInteger(9007199254740992) // false
  10. Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
  11. Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
  12. Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
  13. Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false

这个函数的实现很简单,就是跟安全整数的两个边界值比较一下。

  1. Number.isSafeInteger = function (n) {
  2. return (typeof n === 'number' &&
  3. Math.round(n) === n &&
  4. Number.MIN_SAFE_INTEGER <= n &&
  5. n <= Number.MAX_SAFE_INTEGER);
  6. }

实际使用这个函数时,需要注意。验证运算结果是否落在安全整数的范围内,不要只验证运算结果,而要同时验证参与运算的每个值。

  1. Number.isSafeInteger(9007199254740993)
  2. // false
  3. Number.isSafeInteger(990)
  4. // true
  5. Number.isSafeInteger(9007199254740993 - 990)
  6. // true
  7. 9007199254740993 - 990
  8. // 返回结果 9007199254740002
  9. // 正确答案应该是 9007199254740003

上面代码中,9007199254740993不是一个安全整数,但是Number.isSafeInteger会返回结果,显示计算结果是安全的。这是因为,这个数超出了精度范围,导致在计算机内部,以9007199254740992的形式储存。

  1. 9007199254740993 === 9007199254740992
  2. // true

所以,如果只验证运算结果是否为安全整数,很可能得到错误结果。下面的函数可以同时验证两个运算数和运算结果。

  1. function trusty (left, right, result) {
  2. if (
  3. Number.isSafeInteger(left) &&
  4. Number.isSafeInteger(right) &&
  5. Number.isSafeInteger(result)
  6. ) {
  7. return result;
  8. }
  9. throw new RangeError('Operation cannot be trusted!');
  10. }
  11. trusty(9007199254740993, 990, 9007199254740993 - 990)
  12. // RangeError: Operation cannot be trusted!
  13. trusty(1, 2, 3)
  14. // 3

安全整数和 Number.isSafeInteger()相关推荐

  1. 【ES6】数值的拓展

    [ES6]数值的拓展 二.Number.isFinite(),Number.isNaN() 三.Number.parseInt(),Number.parseFloat() 四.Number.isInt ...

  2. javascript 判断为负数_JavaScript从零开始——标准库(7)

    今天的重点,是数值(Number)对象. 1 概念 Number对象是数值对应的包装对象,可以作为构造函数使用,也可以作为工具函数使用. 作为构造函数时,它用于生成值为数值的对象: 上面代码中,Num ...

  3. javascript --- polyfill中几个常用方法

    ES6中,新增了许多有用的方法,下面分享几个ES6之前得版本写的polyfill Number.EPSILON: // 机器精度,并判断2个数是否相等 if(!Number.EPSILON){Numb ...

  4. ES6标准入门(第二版)pdf

    下载地址:网盘下载 内容简介  · · · · · · ES6(又名 ES2105)是 JavaScript 语言的新标准,2015 年 6 月正式发布后,得到了迅速推广,是目前业界超级活跃的计算机语 ...

  5. “睡服”面试官系列第九篇之数值的扩展(建议收藏学习)

    目录 1. 二进制和八进制表示法 2. Number.isFinite(), Number.isNaN() 3. Number.parseInt(), Number.parseFloat() 4. N ...

  6. ES6的新特性(5)——数值的扩展

    数值的扩展 二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === ...

  7. 自学JavaScript第一天- JS 基础

    自学JavaScript第一天- JS 基础 JS 写在哪里 注释 行内 js 内部 js 外部 js JS 基础语法 语句 大小写 代码块 折行 变量 声明 var .let.const 及作用域 ...

  8. 自学-ES6篇-数值的扩展

    1.二进制和八进制表示法 ES6提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === 503 ...

  9. Javascript 教程/速成/全面 /总结【含代码】

    Javascript 速成 1.dom对象的属性方法 1.1 attribute (attr) 1.2document 1.3element 1.4event 鼠标事件 键盘事件 框架/对象(Fram ...

最新文章

  1. [Beta]第五次 Scrum Meeting
  2. EOS 智能合约源代码解读 (6)合约之action
  3. es elasticsearch 几种常见查询场景 二次分组 java读取es的查询json文件
  4. 《程序员代码面试指南》第一章 栈和队列 设计一个有getMin功能的栈
  5. 给大家介绍一下实现Go并发同步原语的基石
  6. .Net程序猿玩转Android开发---(11)页面跳转
  7. 如何将本地文件夹映射为硬盘盘符?
  8. 3dmax如何导入ies灯
  9. php面向对象编程的特性,什么是面向对象编程(OOP)?面向对象编程的特点
  10. 大一c语言课设之图书管理系统
  11. 轻便简洁的电脑录音软件,免费收藏!
  12. braft-editor 富文本编辑器在谷歌复制图片出现两张
  13. 5个好用的Excel技巧,一秒钟完成一个功能
  14. python账号怎么注销_登录后如何注销
  15. 【Chips】VLSI Final Project:小型卷积核单元设计 项目总结
  16. Plants vs. Zombies(二分)
  17. Java项目:基于Java药品管理系统(计算机毕业设计)
  18. GB/T 8323.2塑料 烟生成 第2 部分:单室法测定烟密度试验方
  19. 更好的包管理器——pnpm
  20. 软考证书=获得职称?软考证书还能这样用

热门文章

  1. 如何快速的打造python 版的vim ide
  2. 进入陕西教育行业市场:TurboMail邮件系统与西京大学合作
  3. 手把手教你在.NET中创建Web服务
  4. EIGRP and the OSPF redistribute
  5. [建议]添加模板功能
  6. html5--5-4 绘制矩形
  7. rhel-server-7.2-x86_64无法联网(VMware环境)
  8. Linux常用命令笔记---创建私有YUM源
  9. Qt 的udpSocket通信
  10. 微软Patterns Practices发布Windows Azure指南第三部分——构建混合应用