js精度缺失和最大安全整数

JS 遵循IEEE 754规范,采用双精度存储(double precision),占用 64 bit。

精度缺失:

  精度缺失最典型例子:

  0.1+0.2 != 0.3(true);0.1+0.2 = 0.30000000000000004

  造成原因,浮点数的表示:

  浮点数:0.1 >> 0.0001 1001 1001 1001…(1001无限循环)0.2 >> 0.0011 0011 0011 0011…(0011无限循环)

  0.1,0.2的二进制表示的是一个无限循环小数,目前 JS 采用的是浮点数标准需要对这种无限循环的二进制进行截取,从而导致了精度丢失,造成了0.1不再是0.1,截取之后0.1变成了 0.100…001,0.2变成了0.200…002,所以两者相加的数大于0.3。

  这个网站统计了不同语言计算0.1+0.2的结果:http://0.30000000000000004.com/ (可以作为学习了解一下)

  解决方案:第三方库有math.jsdecimal.js等。手写方案通常通过转化整数进行计算后还原。

最大安全整数:

  JS 的最大和最小安全整数值:

  最大值:Number.MAX_SAFE_INTEGER  // 9007199254740991 ;最小值:Number.MIN_SAFE_INTEGER)  //-9007199254740991

  当超出这个值范围之后,数字值将不再准确。

  典型案例:在后端发送给前端数据的时候,前端通过Json.parse()进行数据处理的时候,数据值不在范围内就会出现数据错误的问题。

  造成原因:也是由于双精度浮点数导致最大数为2^53 - 1

  解决方案:第三方库有bignumbigint等。手写方案推荐该类字段做字符串处理。

总结:

  从上面两个例子看出,问题的根源其实是关于IEEE 754规范的,这个问题并不只是在Javascript中才会出现,任何使用二进制浮点数的编程语言都会有这个问题。

  要理解出的问题和自拟方案的伙伴可以去查一查了解下IEEE 754标准规范,才能从本质上去看透很多东西。只是单纯寻找解决方案不妨试试推荐的第三方库吧。

原文地址:https://www.cnblogs.com/zhaozhou/p/12834811.html