When the front-end receives back-end data, it encounters the problem of loss of precision

When the front-end receives back-end data, it may encounter the problem of loss of precision

foreword

In the previous project development process, when the front-end received back-end data, it encountered the problem of loss of precision. At that time, the problem was recorded, and this blog aimed at the cause of the problem and solved it in various ways.

problem causes

The problem of precision loss occurs when the front end receives the data returned by the back end, usually because the data type is converted to the Number type in JavaScript during the data transmission process, and the Number type in JavaScript has a certain precision limit, which cannot accurately represent some large or smaller values, resulting in a loss of precision.

The Number type in JavaScript can represent numbers ranging from -9007199254740991 to 9007199254740991, that is, integers and decimals within 2 to the 53rd power. Numbers beyond this range may lose precision or be represented as special Infinity or NaN values. This is because the Number type in JavaScript uses IEEE 754 standard double-precision floating-point representation, using 64-bit binary format to store numbers, including 1 sign bit, 11 exponent bits and 52 mantissa bits. Therefore, the Number type in JavaScript can store 52 significant digits, that is, it can accurately represent up to 15 decimal digits.

How to solve

  1. Use the string type to pass: convert the ID generated by the backend into a string type and then pass it to the frontend, which can avoid the problem of losing the precision of floating point numbers.

  2. Precision processing at the front end: After receiving the ID at the front end, you can use some JavaScript libraries for high-precision calculation and processing, such as decimal.js, bignumber.js, etc., so as to avoid the problem of loss of precision of floating point numbers.

  3. The front-end and back-end uniformly use the same algorithm: You can try to use an algorithm supported by both the front-end and back-end to generate a globally unique ID, which can ensure that the IDs generated by the front-end and back-end are consistent and avoid the problem of loss of precision.

It should be noted that if the problem of precision loss is serious, it may affect the correctness of the system, so it is necessary to choose a suitable solution according to the actual situation.

Solve the example

Backend solution

Add annotations on the corresponding entity properties:

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

The @JsonSerialize annotation is used to specify the serializer used when serializing Java objects into JSON strings, where the
using attribute is used to specify the implementation class of the serializer. In this example,
the using attribute is specified as
com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class, that is, to use the ToStringSerializer class in the Jackson serialization library
to serialize the value of the Java object into a JSON value of string type .

Specifically, in this example, the ToStringSerializer class implements the function of serializing the value of a Java object into a JSON value of type string. For example, if a property of a Java object is of type Long, when using the default serialization method, the value of the property will be serialized as a JSON value of type Number. But when using the ToStringSerializer class, the value of the property will be serialized into a string type JSON value, that is, the value of the property will be converted into a string type before serialization.
The main function of using the ToStringSerializer class is to serialize some properties in the Java object into JSON values ​​of string type, which is usually used to solve some problems such as loss of precision or overflow. For example, in Java, when using double or float type to represent a very large or very small number, precision loss or overflow may occur, then you can use the ToStringSerializer class to convert the value of the property to a string type Then serialize to avoid precision problems.

Example:

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

front-end processing

An example of processing the number 121212121211212564 (17 digits) using the decimal.js library for precision processing on the front end:

  1. Install the decimal.js library:
npm install decimal.js
  1. Introduce decimal.js in the front-end code:
import Decimal from 'decimal.js';
  1. Use the Decimal class for precision handling:
const num = '121212121211212564';
const decimalNum = new Decimal(num);
console.log(decimalNum .toString()); // '121212121211212564'

In this example, we use the Decimal class to convert the given number 121212121211212564 to a data type supported by decimal.js, and then use the toString() method to convert the result to a string type.
It should be noted that if the number you give has a decimal part, then you need to use the toDecimalPlaces() method to specify the precision of the decimal part. If you don't use the toDecimalPlaces() method, there may be precision loss or overflow problems when performing operations.

Guess you like

Origin blog.csdn.net/wangwei021933/article/details/130117070