202111-26更文-java处理长整型精度丢失问题

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

java处理长整型精度丢失问题

前文

本文为遇到的一次长整型精度丢失问题,仅为个人的解决方案,难免有不足之处还请见谅。

问题描述

根据项目需求,有一个是将长整型字段传递给前端显示。进行了一下极端情况测试,采用长整型边界值9223372036854775807。当通过接口调用进行数据查询时,原本应该返回的结果由9223372036854775807,变为9223372036854776000,出现数据精度异常问题。

问题解决方案

首先发现这个是出现了精度异常问题,通过断点跟踪,发现数据库输出的数据正常,service层数据正常,controller层数据正常,advice包装数据同样正常,如下图所示:

image.png 但请求的结果存在精度问题:

image.png 至此处,暂时并未确定数据结果具体出现问题的位置。由于数据的查询结果并无问题,根据经验进行推测,大概应该是long型数据进行序列化时出现问题。此时通过搜索引擎进行了该问题的查询,得到结果为可以采用注解:@JsonSerialize(using=ToStringSerializer.class) 这个接口的含义也就是在进行json数据序列化时,采用string序列化器。至此其实很容易理解,由于long型序列化时会出现精度丢失的问题,那么就直接通过字符串序列化器进行序列化,取代默认的long序列化器,也就解决了精度丢失的问题。经过处理,可以看到结果正确。

扩展

至于上述问题的解决方案及出现原因,进行了进一步的资料查询。通过资料发现,js中number类型的最大值为9007199254740992,小于java中长整型的数据范围,因此出现该问题。

image.png 因此当我们采用字符串序列化器时,则避免了该问题的出现,不会产生精度丢失的问题。

那么如果前端需要显示这个范围的数字呢?比较好的解决办法应该是转为字符串操作,或者说,用字符串拼接成新的字符串,通过截取也就是实际的数据。

后记

  • 千古兴亡多少事?悠悠。不尽长江滚滚流。

猜你喜欢

转载自juejin.im/post/7034715341615792159