超出JavaScript安全整数限制的数字计算-BigInt
JavaScript中的基本数据类Number是双精度浮点数,它可以表示的最大安全范围是正负9007199254740991,也就是2的53次方减一,在浏览器控制台分别输入Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER可查看对应的最大/小值
const max = Number.MAX_SAFE_INTEGER;
// → 9_007_199_254_740_991
// 注意:为了便于阅读,我使用下划线作为分隔符将这些数字分组为千位数。数字文字分隔符提案对普通的JavaScript数字文字使用正确。
将这个最大值加一,可以得到预期的结果:
max + 1;
// → 9_007_199_254_740_992 ✅
但是,如果我们再次增加它,结果不再可以完全表示为JavaScript Number:
max + 2;
// → 9_007_199_254_740_992 ❌
我们会发现max+1和max+2的结果一样。只要我们在JavaScript中获得这个特定的值,就无法判断它是否准确。对安全整数范围以外的整数(即从Number.MIN_SAFE_INTEGER到Number.MAX_SAFE_INTEGER)的任何计算可能会失去精度。出于这个原因,我们只能依靠安全范围内的数字整数值。
BigInt
BigInt是JavaScript中的一个新的原始类型,可以用任意精度表示整数。使用BigInt,即使超出JavaScript Number 的安全整数限制,也可以安全地存储和操作大整数。
chrome 67+开始支持BigInt,本文所有demo都是基于chrome 67。
要创建一个BigInt,在数字后面添加n后缀即可,例如,123变成123n。全局BigInt(number)函数可以用来将Number转换成BigInt。换句话说,BigInt(123) === 123n。让我们用这两种技术来解决我们之前遇到的问题:
BigInt(Number.MAX_SAFE_INTEGER) + 2n;
// → 9_007_199_254_740_993n ✅
我们将两个Number 相乘:
1234567890123456789 * 123;
// → 151851850485185200000 ❌
查看上面两个数字,末尾分别是9和3,9*3=27,然而结果末尾却是000,明显是错误的,让我们用BigInt代替:
1234567890123456789n * 123n;
// → 151851850485185185047n ✅
这次我们得到了正确的结果。
Number 的安全整数限制不适用于BigInt。因此,BigInt我们可以执行正确的整数运算而不必担心失去精度。
BigInt是JavaScript语言中的一个原始类型。因此,可以使用typeof操作符检测到这种类型:
typeof 123;
// → 'number'
typeof 123n;
// → 'bigint'
因为BigInts是一个单独的类型,所以a BigInt永远不会等于a Number,例如 42n !== 42。要比较a BigInt和a Number,在比较之前将其中一个转换为另一个的类型或使用abstract equal(==):
42n === BigInt(42);
// → true
42n == 42;
// → true
当强制转换为布尔型(使用if,&&,||,或Boolean(int)),BigInt按照和Number相同的逻辑转换。
if (0n) {
console.log('if');
} else {
console.log('else');
}
// → logs 'else', because `0n` is falsy.
运算符
BigInt支持最常见的运算符,二元运算符+、-、*、**、/、%都正常工作,按位操作|,&, <<,>>和Number是一样的
(7 + 6 - 5) * 4 ** 3 / 2 % 3;
// → 1
(7n + 6n - 5n) * 4n ** 3n / 2n % 3n;
// → 1n
一元运算符-可以用来表示一个负值BigInt,例如-42n。一元+是不支持的,因为它会破坏asm.js代码,在asm.js中+x总是抛出异常。
另外一个问题是,不允许在BigInt和Number 之间混合运算。看看这个例子:
BigInt(Number.MAX_SAFE_INTEGER) + 2.5;
// → ??超出JavaScript安全整数限制的数字计算-BigInt的更多相关文章
- algorithm++:一个整数称为是:【幸运数】,如果这个整数的各位数字的平方和为1或者反复计算各位数字的平方和为1 例如 19 是个幸运数
1):一个整数称为是:[幸运数],如果这个整数的各位数字的平方和为1或者反复计算各位数字的平方和为1 例如 19 是个幸运数 coding:java程序实现 import org.junit.Test ...
- JS数字计算精度误差的解决方法
本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助. 如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0. ...
- JavaScript超大整数加法
原文:JavaScript超大整数加法 什么是「超大整数」? JavaScript 采用 IEEE754标准 中的浮点数算法来表示数字 Number. 我也没花时间去详细了解 IEEE754标准 ,但 ...
- Linux Shell 数字计算与比较
直接上脚本, 使用$(())以及$[]进行数字计算 数值比较:n1 -eq n2检查n1是否等于n2 n1 -le n2检查n1是否小于等于n2n1 -ge n2检查n1是否大于等于n ...
- javascript获取整数随机数
javascript获取整数随机数 // 从4到10的随机数,|0是生成正整数 var numBars = Math.random()*6+4|0; 也可以通过右移0位(或者左移0位)进行取整 var ...
- JS数字计算精度问题解决
add(a, b) {//相加 var c, d, e; try { c = a.toString().split(".")[1].length; } catch (f) { c ...
- (转)linux shell 数字计算详解
代码中免不了要进行各种数据计算.抛开科学计算不提,普通的计算占地,百分比,同比,环比等需求就很常见.linux shell中进行数字计算,主要有如下几种方式: 1.bc bc是比较常用的linux计算 ...
- 笔试算法题(29):判断元素范围1到N的数组是否有重复数字 & 计算整数的7倍
出题:一个长度为N的数组,其中的元素取值范围是1到N,要求快速判断数组是否存在重复数字: 分析: 解法1:如果N个元素的范围都是在1到N,所以如果没有重复元素,则每一个位置恰好可以对应数组中的一个元素 ...
- JavaScript数字计算精度丢失的问题和解决方案
一.JS数字精度丢失的一些典型问题 1. 两个简单的浮点数相加:0.1 + 0.2 != 0.3 // true,下图是firebug的控制台截图: 看看java的计算结果:是不是让你很不能接受 再来 ...
随机推荐
- Confluence 6 基本性能问题诊断步骤
基本性能问题诊断步骤 开始下面的程序: 进入 Troubleshooting Confluence hanging or crashing页面找到已知的主要性能问题. 进行页面 Performance ...
- Swift 新增fileprivate 详解
以前项目中只要用了private 那么在同一个文件同一个类中还是能访问的(比如一个类中写了一个extension) swift3.0现在不行了 新增了一个fileprivate 的访问控制 以前的p ...
- 遇到的一个移动端从下往上过渡的弹框,在Android下过渡动画的优化问题。
优化之前: /* 分享弹框样式 */ .popUpDiv { width: 100vw; height: 100vh; transition: all 0.5s ease; position: fix ...
- day12 函数的嵌套调用 闭包函数,函数对象
函数嵌套: 函数嵌套: 嵌套指的是,一个物体包含另一个物体,函数嵌套就是一个函数包含另一个函数 按照函数的两个阶段 嵌套调用 指的是在函数的执行过程中调用了另一个函数,其好处可以简化外层大函数的代码, ...
- 初识dubbo
1. 为什么需要 Dubbo(摘自http://dubbo.apache.org/zh-cn/docs/user/quick-start.html) 随着互联网的发展,网站应用的规模不断扩大,常规的垂 ...
- LeetCode(116):填充同一层的兄弟节点
Medium! 题目描述: 给定一个二叉树 struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *n ...
- LeetCode(96): 不同的二叉搜索树
Medium! 题目描述: 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: ...
- 【层次聚类】python scipy实现
层次聚类 原理 有一个讲得很清楚的博客:博客地址 主要用于:没有groundtruth,且不知道要分几类的情况 用scipy模块实现聚类 参考函数说明: pdist squareform linkag ...
- 【ssh】端口转发
来源:https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/ 非常非常好用,可以通过跳板解决两台服务器无法连接的问题 第一部分 概述 ...
- Python基础之模块与包
一.模块 1.什么是模块? 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2.为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函 ...