Java 浮点型(Double,Float)精度丢失解决方案

栏目: IT技术 · 发布时间: 5年前

内容简介:最近公司某小伙子做了一个商城的微信支付相关的接口,其中包含退款,在测试过程中发现部分单据没有退款,微信支付提示退款金额跟支付金额不匹配(大于支付金额),检查数据库和调试过程中,发现商品的单价和手工计算出来的总价是跟订单金额匹配的,实在无法确认问题原因最终bug转向我来排查,于是有了此文由于手工计算出来的金额跟实际支付的金额是能匹配上的,所以一开始我以为是订单已经进行了部分退款,再次全部退款的话肯定会被微信阻止,因为这样的话就会出现超退。去微信支付平台排查是否有退款,结果发现并没有退款

前言

最近公司某小伙子做了一个商城的微信支付相关的接口,其中包含退款,在测试过程中发现部分单据没有退款,微信支付提示退款金额跟支付金额不匹配(大于支付金额),检查数据库和调试过程中,发现商品的单价和手工计算出来的总价是跟订单金额匹配的,实在无法确认问题原因最终bug转向我来排查,于是有了此文

排查

由于手工计算出来的金额跟实际支付的金额是能匹配上的,所以一开始我以为是订单已经进行了部分退款,再次全部退款的话肯定会被微信阻止,因为这样的话就会出现超退。

第一步:是否已经部分退款

去微信支付平台排查是否有退款,结果发现并没有退款

由于微信平台没有查询到此单的退款,那么说明不是超退的问题,可能是传入的订单金额有问题,但是大部分单据又可以退款,所以也暂时陷入了僵局,不过为了保险起见,还是去看了一下传参处

第二步:检查传参

检查微信退款方法传参时,看了传入参数,由于微信传参的单位是分,所以看到传参处传入退款总金额代码(int)(100)*商品单价*退货数量(这里只是伪代码,多个商品肯定还要相加计算的),粗略一看没有问题,仔细一看不对,总价是直接double类型的乘以数量在乘以100再强转为int类型传入的,按照理论上来说是没有问题的,因为我们商品价格都是精确到分的,但是只是理论上,实际上就是 Java 的double类型有个大坑(不只是Java,JavaScript,c#等很多语言都有这个问题),最终在代码中进行总价计算,发现确定是因为这个原因,导致计算出来的退款金额比应退金额多了1分钱,所以导致退款失败

起因

之所以会发生精度丢失,是因为编程语言在十进制和二进制相互转换时,会出现除不断的问题,就导致了精度丢失 Java 浮点型(Double,Float)精度丢失解决方案

详情可以查看知乎原文,我觉得解释的非常不错

如何理解double精度丢失问题?

解决办法

解决办法有2种:

第一种是电商行业通常的做法,将所有价格用分来表示,数据库中保存int类型,因为通常情况下,商品价格只需要精确到分,分也是正常电商的最小单位,前端显示时通过将分转化成元来显示,但是后端计算都是分来计算,也就是int型来计算,这样就不会出现精度丢失的问题,当然也可能会出现int最大值的问题,当然一般情况下也可以忽略这个问题毕竟没有几个商品价格或者订单能超过int的最大值了,当然系统订单总价可能会超过,这么单独处理一下就行了

第二种就是使用BigDecimal类进行计算了,由于我们系统一开始就是用元来表示,所以只能用DigDecimal来计算避免精度丢失了,具体BigDecimal的用法可以百度

结尾

通过这次问题,首先要注意就是代码中规范好,所有浮点类型计算的都使用BigDecimal进行计算,并且要写入开发规范文档,其次就是类似于价格这类的,以后最好还是用分来进行处理


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

重来2

重来2

[美] 贾森·弗里德、[美] 戴维·海涅迈尔·汉森 / 苏西 / 中信出版社 / 2014-4-8 / 39.00元

“不再需要办公室”,这不仅仅是未来才有的事——它已经发生了。现在,轮到你迈开脚步,跟上时代的步伐了。 上百万的员工和成千上万的企业已经发现了远程工作的乐趣和好处。然而,远程工作方式还没有成为常见的选择。事实上,远程工作的技术手段都已齐备。还没有升级换代的,是人们的思想。 这本书的目的就是帮你把想法升级换代。作者会向你展示远程工作的诸多好处:可以找到最优秀的人才,从摧残灵魂的通勤路上解脱......一起来看看 《重来2》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具