js的数据精度问题

19 年 10 月 17 日 星期四
458 字
3 分钟

前后端数值传递中的 js数值精度损失问题

问题图示

原数值

后端传递的值为1176037389258023221

接收值 js接收到的值为:1176037389258023200

产生原因

JavaScript的Number类型能表示并进行精确算术运算的安全整数范围为:正负2^53^-1,16位数

所以对于后台的long类型数据,在数值过大时,就会出现精度损失。

解决方案

由于接收时的数据就是损失状态,所以不好在js中直接处理,当然,也有一些方式能够解决这个问题。比如jison,通过它可以对要接收的数据的重新定义json parser

不过,这种情况一般都会交给后端解决,让传递的值转为字符串,这样就不会有精度损失的问题。

后端(java)解决方式示例:

①使用@JsonSerialize注解,作用于实例域的Get方法,在数据输出时将其转为字符串,如:

java
package cn.shirtiny.community.SHcommunity.DTO;

import ...

@Data
public class InvitationDTO {
 //输出时转字符串
    @JsonSerialize(using = ToStringSerializer.class)//作用于属性的get方法
    private long invitationId;//主键id
    //输出时转字符串
    @JsonSerialize(using = ToStringSerializer.class)
    private long authorId; //作者id
    @JsonSerialize(using = ToStringSerializer.class)
    private long gmtCreate;//作者的注册时间
}

②直接将DTO对象关于Long类型的属性,设为String类型,在与数据库交互时,进行类型转换:

java
package cn.shirtiny.community.SHcommunity.DTO;

import ...

@Data
public class InvitationDTO {
    private String invitationId;//主键id
    private String authorId; //作者id
    private String gmtCreate;//作者的注册时间
}

注:这里我使用的是Mybatis-Plus,在交互时,会自动进行BigIntString的转换。如果需要字符串类型的uuid,可以使用以下方式,在mapper里写

java
// 返回String类型的UUID
@Select("SELECT UUID_SHORT()")
String getShortStrUUid();

③全局类型转换器,这个就需要考虑很多东西了。

文章标题:js的数据精度问题

文章作者:shirtiny

文章链接:https://kizamu.anror.com/posts/js-number-limit[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。