js精度丢失的问题

这篇具有很好参考价值的文章主要介绍了js精度丢失的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.js精度丢失的常见问题,从常见的浮点型进行计算,到位数很长的munber类型进行计算都会造成精度丢失的问题,
首先我们看一个问题:

0.1 + 0.2  !==  0.3  // true

let a =  9007199254740992
a + 1 == a // true

那么js为什么会出现精度丢失的问题:

计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit

比如:

0.1 >> 0.0001 1001 1001 1001…(1001无限循环)
0.2 >> 0.0011 0011 0011 0011…(0011无限循环)

此时只能模仿十进制进行四舍五入了,但是二进制只有 0 和 1 两个,于是变为 0 舍 1 入。这即是计算机中部分浮点数运算时出现误差,丢失精度的根本原因。

大整数的精度丢失和浮点数本质上是一样的,尾数位最大是52位,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即 9007199254740992。

大于 9007199254740992 的可能会丢失精度

9007199254740992 >> 10000000000000…000 // 共计 53 个 0
9007199254740992 + 1 >> 10000000000000…001 // 中间 52 个 0
9007199254740992 + 2 >> 10000000000000…010 // 中间 51 个 0
当你做如下计算的时候

9007199254740992 + 1 // 丢失
9007199254740992 + 2 // 未丢失
9007199254740992 + 3 // 丢失
9007199254740992 + 4 // 未丢失

对于整数,前端出现问题的几率可能比较低,毕竟很少有业务需要需要用到超大整数,只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度。

对于小数,前端出现问题的几率还是很多的,尤其在一些电商网站涉及到金额等数据。解决方式:把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数)

// 0.1 + 0.2
(0.110 + 0.210) / 10 == 0.3 // true

对于过大的数字:
可以用bigint,应为number的基本类型不能超过2^53,不然就会出现精度丢失,为了解决这个限制,在ECMAScript标准中出现了BigInt。
BigInt可以表示任意大的整数

但是要注意写法:

let result=124569875984123677888999;  //估摸着这一步就在前端已经精度丢失了
String(BigInt(result));

let result=BigInt(124569875984123677888999);   //这里也已经精度丢失了
String(result);
// 上面两种都是错误的写法

// 正确写法:
let result=124569875984123677888999n; 
String(result);

除了以上方式,还可以借助第三方库
BigNumber.js:提供了超高精度的数字处理能力,可以解决精度丢失问题。
decimal.js:提供了类似于 Python Decimal 的类型,可以精确表示浮点数,解决精度丢失问题。文章来源地址https://www.toymoban.com/news/detail-622861.html

npm install bignumber.js --save

let x = new BigNumber(123.4567);
let y = BigNumber('123456.7e-3');
let z = new BigNumber(x);
x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z);      // true

let x = new BigNumber('1111222233334444555566');
x.toString();                       // "1.111222233334444555566e+21"
x.toFixed();                        // "1111222233334444555566"

// Precision loss from using numeric literals with more than 15 significant digits.
new BigNumber(1.0000000000000001)         // '1'
new BigNumber(88259496234518.57)          // '88259496234518.56'
new BigNumber(99999999999999999999)       // '100000000000000000000'

// Precision loss from using numeric literals outside the range of Number values.
new BigNumber(2e+308)                     // 'Infinity'
new BigNumber(1e-324)                     // '0'

// Precision loss from the unexpected result of arithmetic with Number values.
new BigNumber(0.7 + 0.1)                  // '0.7999999999999999'


npm install --save decimal.js

 const a = 9.99;
 const b = 8.03;
 
 // 加法
 let c = new Decimal(a).add(new Decimal(b)) 
 
 // 减法
 let d = new Decimal(a).sub(new Decimal(b))
 
 // 乘法
 let e = new Decimal(a).mul(new Decimal(b))
 
 // 除法
 let f = new Decimal(a).div(new Decimal(b))

到了这里,关于js精度丢失的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录--前端金额运算精度丢失问题及解决方案

    前端开发中难免会遇到价格和金额计算的需求,这类需求所要计算的数值大多数情况下是要求精确到小数点后的多少位。但是因为JS语言本身的缺陷,在处理浮点数的运算时会出现一些奇怪的问题,导致计算不精确。 本文尝试从现象入手,分析造成这一问题原因,并总结和整

    2024年02月19日
    浏览(46)
  • 后端传long类型数据到前端精度丢失问题

    在 Spring Boot 中,将 long 类型传输到前端时,会发现该类型的值可能会出现精度丢失的问题。 这是因为在 JavaScript 中,数字类型默认会被转换为双精度浮点数,而双精度浮点数的精度有限,只能精确表示 2 的 53 次方以内(即 Number.MAX_SAFE_INTEGER,约为 9 x 10^15)的整数。对于超过

    2024年02月15日
    浏览(48)
  • 前端接收后端数据时,遇到精度丢失的问题

    之前项目开发过程中遇到过前端接收后端数据时,遇到精度丢失的问题。当时进行了问题记录,本篇博客针对于这个问题进行问题原因并进行多种方式解决这个问题。 前端接收后端返回的数据时出现精度丢失问题,通常是因为在数据传输过程中,数据类型被转换为了 JavaScr

    2024年02月02日
    浏览(70)
  • 如何解决前端传递数据给后端时精度丢失问题

    有时候我们在进行修改操作时,发现修改既不报错也不生效。我们进行排查后发现服务器端将数据返回给前端时没有出错,但是前端js将数据进行处理时却出错了,因为id是Long类型的,而js在处理后端返回给前端的Long类型数据时只能处理前16位,后3位进行了四舍五入操作,例

    2024年02月09日
    浏览(63)
  • 如何完美解决前端数字计算精度丢失与数字格式化问题?

    大家好,我是木瓜太香,做前端开发经常会遇到数字计算精度丢失的问题,和数字格式化的麻烦问题,好不容易找到了可以解决这些问题的库结果用起来不够方便,例如 bignumber.js decimal.js 等编写体验不好,这篇文章来帮助你完美解决这些问题 接下来我们根据以下两个问题展

    2024年02月16日
    浏览(47)
  • SpringBoot返回前端Long类型字段丢失精度问题及解决方案

    Java服务端返回Long整型数据给前端,JS会自动转换为Number类型。而Long类型能表示的最大值为(),当数值超过JS中Number类型的最大值()时,就会丢失精度。 首先,引入依赖。 新建一个自定义大数据序列化类,如下: 新建Jackson配置类 本文针对Java服务端返回Long整型数据给前端时

    2024年03月22日
    浏览(105)
  • JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js

    一、计算精度现象举例 举例1、加法 举例2、减法    举例3、乘法 举例3、除法 二、JS为什么会有计算精度的问题 JavaScript 内部只有一种数字类型Number,也就是说,JavaScript 语言的底层根本没有整数,所有数字都是以IEEE-754标准格式64位浮点数形式储存,1与1.0是相同的。因为有

    2024年02月10日
    浏览(42)
  • 前端处理后端传来的Long型数据精度丢失的问题--对象转换器Jackson0bjectMapper

    1、问题描述 前端提交参数 后端处理 前端js对long型数据进行处理时丢失精度(只能保证16位),导致提交的id和数据库中的id不一致。 2、 问题实现 如何解决这个问题? 我们可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串 3、具体代码实现–对象

    2024年02月16日
    浏览(88)
  • SpringBoot后端Long数据传到前端js精度损失问题

    在对应的字段上添加注解,将 Long 转为 String 后传输。 在 js 对应的结果接收上使用 BigInt 。

    2024年02月19日
    浏览(57)
  • js浮点数四则运算精度丢失以及toFixed()精度丢失解决方法

    1、四则运算精度丢失: 2、toFixed() 四舍五入精度丢失: js采用64位浮点数表示法(几乎所有现代编程语言所采用),这是一种二进制表示法。二进制浮点数表示法并不能精确表示类似 0.1 这样简单的数字。 这个问题不只在js中才会出现,在任何使用二进制浮点数的编程语言中

    2024年02月05日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包