前端接收后端数据时,遇到精度丢失的问题

简介: 前端接收后端数据时,遇到精度丢失的问题

前端接收后端数据时,可能会遇到精度丢失的问题


前言

之前项目开发过程中遇到过前端接收后端数据时,遇到精度丢失的问题。当时进行了问题记录,本篇博客针对于这个问题进行问题原因并进行多种方式解决这个问题。

问题原因

前端接收后端返回的数据时出现精度丢失问题,通常是因为在数据传输过程中,数据类型被转换为了 JavaScript 中的 Number 类型,而 JavaScript 的 Number 类型有一定的精度限制,无法精确表示一些较大或较小的数值,从而导致精度丢失。


JavaScript 中的 Number 类型可以表示的数字范围是 -9007199254740991 到 9007199254740991,即在 2 的 53 次方以内的整数和小数,超过这个范围的数字可能会失去精度或被表示为特殊的 Infinity 或 NaN 值。这是由于 JavaScript 中的 Number 类型采用的是 IEEE 754 标准的双精度浮点数表示法,使用 64 位二进制格式存储数字,其中 1 位符号位、11 位指数位和 52 位尾数位。因此,JavaScript 中的 Number 类型能够存储的有效数字位数为 52 位,即最多可以精确表示 15 位十进制数字。

如何解决

1.使用字符串类型传递:将后端生成的 ID 转换成字符串类型后再传递给前端,这样可以避免浮点数精度丢失的问题。

2.在前端进行精度处理:在前端接收到 ID 后,可以使用一些 JavaScript 库来进行高精度计算和处理,例如 decimal.js、bignumber.js 等,这样可以避免浮点数精度丢失的问题。

3.前后端统一使用相同的算法:可以尝试使用前后端都支持的算法来生成全局唯一 ID,这样可以保证前后端生成的 ID 是一致的,避免精度丢失的问题。


需要注意的是,如果精度丢失的问题比较严重,可能会影响到系统的正确性,因此需要根据实际情况选择适合的解决方法。

解决示例

后端解决方式

在对应的实体属性上添加注解:

@JsonSerialize(using = com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class)

@JsonSerialize 注解用于指定在将 Java 对象序列化为 JSON 字符串时使用的序列化器,其中

using 属性用于指定序列化器的实现类。在这个例子中,

using 属性指定为

com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class,即使用 Jackson 序列化库中的

ToStringSerializer 类来将 Java 对象的值序列化为字符串类型的 JSON 值。


具体来说,在这个例子中,ToStringSerializer 类实现了将 Java 对象的值序列化为字符串类型的 JSON 值的功能。例如,如果 Java 对象的一个属性是 Long 类型,使用默认的序列化方式时,该属性的值会被序列化为一个数字类型的 JSON 值。但是使用 ToStringSerializer 类时,该属性的值会被序列化为一个字符串类型的 JSON 值,即将该属性的值转换为字符串类型后再进行序列化。

使用 ToStringSerializer 类的主要作用是将 Java 对象中的某些属性序列化为字符串类型的 JSON 值,这通常用于解决一些精度丢失或溢出等问题。例如,在 Java 中,当使用 double 或 float 类型来表示一个非常大或非常小的数时,可能会出现精度丢失或溢出的问题,这时可以使用 ToStringSerializer 类将该属性的值转换为字符串类型后再进行序列化,避免精度问题。


示例:

@JsonSerialize(using = com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class)
//解决雪花算法生成后,前端接收后缺失精度问题
private BigInteger id;

前端进行处理

将数字121212121211212564(17位)使用 decimal.js 库在前端进行精度处理的示例:

  1. 安装 decimal.js 库:
npm install decimal.js
  1. 在前端代码中引入 decimal.js:
import Decimal from 'decimal.js';
  1. 使用 Decimal 类来进行精度处理:
const num = '121212121211212564';
const decimalNum = new Decimal(num);
console.log(decimalNum .toString()); // '121212121211212564'

在这个示例中,我们使用 Decimal 类将给定的数字 121212121211212564 转换成了 decimal.js 支持的数据类型,然后使用 toString() 方法将结果转换成字符串类型。

需要注意的是,如果你给出的数字有小数部分,那么你需要使用 toDecimalPlaces() 方法来指定小数部分的精度。如果你不使用 toDecimalPlaces() 方法,那么在进行运算时,可能会出现精度丢失或者溢出的问题。

目录
相关文章
|
22天前
|
前端开发 JavaScript 关系型数据库
从前端到后端:构建现代化Web应用的技术探索
在当今互联网时代,Web应用的开发已成为了各行各业不可或缺的一部分。从前端到后端,这篇文章将带你深入探索如何构建现代化的Web应用。我们将介绍多种技术,包括前端开发、后端开发以及各种编程语言(如Java、Python、C、PHP、Go)和数据库,帮助你了解如何利用这些技术构建出高效、安全和可扩展的Web应用。
|
24天前
|
前端开发 小程序 Java
uniapp上传图片 前端以及java后端代码实现
uniapp上传图片 前端以及java后端代码实现
34 0
|
4天前
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
22 1
|
2天前
|
存储 前端开发 JavaScript
从前端到后端:构建全栈应用的关键技术探究
在当今互联网时代,全栈开发已经成为了越来越多开发者的追求目标。本文将深入探讨从前端到后端构建全栈应用所需的关键技术,涵盖了前端框架选择、后端语言与框架、数据库设计以及前后端通信等方面,帮助读者全面了解全栈开发的必备技能和工具。
|
2天前
|
JSON 前端开发 Java
管理系统总结(前端:Vue-cli, 后端Jdbc连接mysql数据库,项目部署tomcat里)
管理系统总结(前端:Vue-cli, 后端Jdbc连接mysql数据库,项目部署tomcat里)
|
6天前
|
前端开发 JavaScript Java
前端与后端:构建现代Web应用的双翼
前端与后端:构建现代Web应用的双翼
|
14天前
|
移动开发 前端开发 JavaScript
亘古难题——前端开发or后端开发
亘古难题——前端开发or后端开发
|
14天前
|
存储 缓存 前端开发
前端如何利用indexDB进行数据优化
使用IndexedDB作为浏览器内置的客户端数据库,用于存储大量数据和实现离线支持。它能缓存常用数据,减少服务器请求,提高用户体验。IndexedDB支持数据索引、复杂查询及版本管理,允许离线操作并同步到服务器。但需熟悉其异步API,可借助Dexie.js、localForage等库简化使用。
|
15天前
|
存储 缓存 负载均衡
跨越界限:前端与后端的协同优化
在当今快节奏的技术环境下,前端与后端的协同优化成为了提升应用性能和用户体验的关键。本文探讨了如何通过前后端的紧密合作,实现更高效的数据传输、渲染优化以及系统性能提升,从而构建出更加流畅、响应迅速的应用程序。
|
19天前
|
小程序 前端开发 JavaScript
小程序全栈开发:前端与后端的完美结合
【4月更文挑战第12天】本文介绍了小程序全栈开发,涵盖前端和后端的关键点。前端使用WXML和WXSS进行页面结构和样式设计,JavaScript处理逻辑及组件使用;后端采用Node.js等语言处理业务逻辑、数据库设计和API接口开发。前端与后端通过数据交互实现结合,采用前后端分离模式,支持跨平台运行。调试测试后,提交微信审核并上线运营。掌握前端后端结合是小程序成功的关键。