Cuando el front-end recibe datos de back-end, se encuentra con el problema de la pérdida de precisión

Cuando el front-end recibe datos de back-end, puede encontrar el problema de pérdida de precisión

prefacio

En el proceso de desarrollo del proyecto anterior, cuando el front-end recibía datos del back-end, se encontraba con el problema de la pérdida de precisión. En ese momento, se registró el problema. Este blog apunta a la causa de este problema y lo resuelve de varias maneras.

causas del problema

El problema de la pérdida de precisión ocurre cuando el front-end recibe los datos devueltos por el back-end, generalmente porque el tipo de datos se convierte al tipo Número en JavaScript durante el proceso de transmisión de datos, y el tipo Número en JavaScript tiene un cierto límite de precisión, que no puede representar con precisión algunos valores grandes o pequeños, lo que resulta en una pérdida de precisión.

El tipo Número en JavaScript puede representar números que van desde -9007199254740991 hasta 9007199254740991, es decir, enteros y decimales dentro de la potencia 2 a la 53. Los números más allá de este rango pueden perder precisión o ser representados como valores especiales de NaN o Infinito. Esto se debe a que el tipo Número en JavaScript utiliza la representación de punto flotante de precisión doble estándar IEEE 754, utilizando un formato binario de 64 bits para almacenar números, incluidos 1 bit de signo, 11 bits de exponente y 52 bits de mantisa. Por lo tanto, el tipo Número en JavaScript puede almacenar 52 dígitos significativos, es decir, puede representar con precisión hasta 15 dígitos decimales.

Cómo resolver

  1. Use el tipo de cadena para pasar: convierta el ID generado por el backend en un tipo de cadena y luego páselo al frontend, lo que puede evitar el problema de perder la precisión de los números de coma flotante.

  2. Procesamiento de precisión en el front-end: después de recibir la ID en el front-end, puede usar algunas bibliotecas de JavaScript para el cálculo y el procesamiento de alta precisión, como decimal.js, bignumber.js, etc., para evitar el problema de pérdida de precisión de los números de coma flotante.

  3. El front-end y el back-end usan uniformemente el mismo algoritmo: puede intentar usar un algoritmo compatible tanto con el front-end como con el back-end para generar una ID única global, que puede garantizar que las ID generadas por el front-end y el back-end. end y back-end son consistentes y evitan el problema de la pérdida de precisión.

Cabe señalar que si el problema de pérdida de precisión es grave, puede afectar la corrección del sistema, por lo que es necesario elegir una solución adecuada de acuerdo con la situación real.

Resuelve el ejemplo

solución de fondo

Agregue anotaciones en las propiedades de la entidad correspondiente:

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

La anotación @JsonSerialize se usa para especificar el serializador que se usa al serializar objetos Java en cadenas JSON, donde el
atributo using se usa para especificar la clase de implementación del serializador. En este ejemplo,
el atributo de uso se especifica como
com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class, es decir, para usar la clase ToStringSerializer en la biblioteca de serialización de Jackson
para serializar el valor del objeto Java en un JSON valor de tipo cadena.

Específicamente, en este ejemplo, la clase ToStringSerializer implementa la función de serializar el valor de un objeto Java en un valor JSON de tipo cadena. Por ejemplo, si una propiedad de un objeto Java es de tipo Long, al usar el método de serialización predeterminado, el valor de la propiedad se serializará como un valor JSON de tipo Número. Sin embargo, al usar la clase ToStringSerializer, el valor del atributo se serializará en un valor JSON de tipo cadena, es decir, el valor del atributo se convierte en un tipo de cadena antes de la serialización.
La función principal de usar la clase ToStringSerializer es serializar ciertas propiedades en el objeto de Java en valores JSON de tipo cadena, que generalmente se usa para resolver algunos problemas como la pérdida de precisión o el desbordamiento. Por ejemplo, en Java, cuando se usa el tipo doble o flotante para representar un número muy grande o muy pequeño, puede ocurrir una pérdida de precisión o un desbordamiento, luego puede usar la clase ToStringSerializer para convertir el valor de esta propiedad en un tipo de cadena. evitar problemas de precisión.

Ejemplo:

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

procesamiento frontal

Un ejemplo de procesamiento del número 121212121211212564 (17 dígitos) utilizando la biblioteca decimal.js para un procesamiento de precisión en la interfaz:

  1. Instale la biblioteca decimal.js:
npm install decimal.js
  1. Introduce decimal.js en el código front-end:
import Decimal from 'decimal.js';
  1. Utilice la clase Decimal para el manejo de precisión:
const num = '121212121211212564';
const decimalNum = new Decimal(num);
console.log(decimalNum .toString()); // '121212121211212564'

En este ejemplo, usamos la clase Decimal para convertir el número dado 121212121211212564 en un tipo de datos admitido por decimal.js, y luego usamos el método toString() para convertir el resultado en un tipo de cadena.
Cabe señalar que si el número que proporciona tiene una parte decimal, debe usar el método toDecimalPlaces() para especificar la precisión de la parte decimal. Si no usa el método toDecimalPlaces(), puede haber problemas de pérdida de precisión o desbordamiento al realizar operaciones.

Supongo que te gusta

Origin blog.csdn.net/wangwei021933/article/details/130117070
Recomendado
Clasificación