超出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'
因为BigInt
s是一个单独的类型,所以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的计算结果:是不是让你很不能接受 再来 ...
随机推荐
- vue 中动态绑定class 和 style的方法
先列举一些例子 :class="['content',{'radioModel':checkType}]" :class="['siteAppListDirNode',{ ...
- 查看mysql 默认端口号和修改端口号
1. 登录mysql mysql -u root -p //输入密码 2. 使用命令show global variables like 'port';查看端口号 mysql> show glo ...
- 使用asp.net MVC的 HtmlHelper 时遇到的小问题,报错:Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
异常信息:Templates can be used only with field access, property access, single-dimension array index, or ...
- 集腋成裘-01-html -html基础
1 标签 1.1 单标签 注释标签 <!-- 注释标签 --> 换行标签 <br/> 水平线 <hr/> <img src="图片来源" ...
- maven如果正常配置不成功,就按照我的就可以配置成功了
常规的配置如下 非常规的配置 如果上面都没有问题,还是不能创建成功,就是maven配路径的问题,如图所示 如下图所示即是正确配置
- office web apps搭建与解决方案
微软office在线预览解决方案https://view.officeapps.live.com/op/view.aspx?src=http://storage.xuetangx.com/public ...
- Windows Server 2008/2012 计划任务配置执行bat
首先Windows Server 2008不同于其他服务器操作系统和Windows Server 2003有着很大的区别,计划任务的名称是“任务计划程序”不在控制面板里,而是在“管理工具”里.由于服务 ...
- vector的 []
摘自<C++编程剖析> #include <iostream> #include <vector> using namespace std; int main() ...
- nginx的with-http_sub_module模块使用之替换字符串
一.介绍 该ngx_http_sub_module模块是一个过滤器,通过将一个指定的字符串替换为另一个字符串来修改响应.该模块不是默认生成的,它应该使用--with-http_sub_module 配 ...
- python全栈开发day67--字段类型、字段属性、ORM回顾
一.回顾总结 https://www.cnblogs.com/maple-shaw/articles/9323320.html 1. 视图 1. CBV 和 FBV from django.views ...