java项目中与金额有关的计算注意事项

java项目中与金额有关的计算注意事项

前言:

在项目中,财务相关的数据计算可能会通过项目进行各种计算以及存库,本篇讲述这个过程中的注意事项。

1.浮点型的误差

浮点型由于其定义的原因,在使用的时候总会存在误差,以下以pgsql为例:

sql 复制代码
select 0.1::float+0.2::float; -- 返回结果:0.30000000000000004

可以看到这就出现了误差,尾数末尾有个4,在计算中进行比较的时候可能就会出现错误,比如0.1+0.2 > 0.3了。

所以在项目中与金额有关的计算全部避免使用浮点型,像java中的double,float以及对应的封装类,pgsql中的float等,均避免使用。

2.数据库中如何存储

第一小节讲述了浮点型可能造成的误差,那么数据库中应该如何存储呢,以pgsql为例,应当使用decimal或者numeric存储,这种类型的固定精度和标度的数值可以避免浮点数误差导致的问题。

3.java中如何避免浮点精度问题

java中有一个BigDecimal类,与pgsql中decimal和numeric类似,都是固定精度和标度的数值,都不会有浮点型的误差,但是需要注意的是,在使用的时候不能使用Double接收了前端参数之后,再由这个double类型初始化BigDecimal,从前端接受和后端取库中数据以及计算,应当全程使用BigDecimal,避免中间任意一环使用浮点数。

4.其他案例

在避免了浮点数精度导致的问题的时候,金额计算可能会伴随着其他问题,下面进行举例:

以一个简单的奖金计算为例,一个项目有若干个里程碑,每个里程碑有对应的进度,里程碑达成后,会生成里程碑进度×项目金额的奖金,由于金额的最小单位是分,所以数据库中存储保留两位小数并且去除多余尾数的时候向下取整。假设项目金额10000.57,有两个里程碑,第一个里程碑进度33%,第二个里程碑进度67%,总和为100%。

当第一个里程碑达成的时候,获得的奖金为10000.57×0.33=3,300.1881,保留两位小数后获得结果3,300.18,第二个里程碑达成后获取奖金10000.57×0.67=6,700.3819,保留两位小数取得结果6700.38,两次奖金相加3300.18+6700.38=10000.56,总的奖金生成少了1分钱,这一分钱看似无所谓,财务计算的时候能要命。

  • 那么应该如何避免呢?
    • 首先这个问题是怎么造成的呢?这个问题是因为进行了保留小数的操作,造成的,那么就有两种方案:
      • 不舍去多余小数。(但是如果一定要舍去的情况咋办呢qwq,其实讲这个案例就是为了说明保留小数位数后造成最后总金额算出来不对)
      • 在某个环节补回来,上面这个案例就可以在最后一个里程碑达成之后,和总奖金进行计算,将误差的金额补回来。

5.总结

  • 数据库存储金额的时候避免使用浮点数,以pgsql为例,使用numeric或者decimal。
  • java中避免浮点数精度问题的时候,从接受前端数据到后端存库以及中间计算,全程使用BigDecimal接受前端参数和进行运算以及存库。
  • 金额相关的计算都应该慎重考虑,不止浮点数造成的误差,保留小数位数的操作可能也会造成误差,需要在某些环节补回来。
    最后欢迎各位大佬批评指正QWQ
相关推荐
MY_TEUCK42 分钟前
Sealos 平台部署实战指南:结合 Cursor 与版本发布流程
java·人工智能·学习·aigc
2401_873479401 小时前
如何利用IP查询定位识别电商刷单?4个关键指标+工具配置方案
开发语言·tcp/ip·php
我爱cope1 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
菜鸟学Python1 小时前
Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?
开发语言·python·django·flask·fastapi
朝新_2 小时前
【Spring AI 】图像与语音模型实战
java·人工智能·spring
RH2312112 小时前
2026.4.16Linux 管道
java·linux·服务器
zmsofts2 小时前
java面试必问13:MyBatis 一级缓存、二级缓存:从原理到脏数据,一篇讲透
java·面试·mybatis
浪浪小洋2 小时前
c++ qt课设定制
开发语言·c++
charlie1145141913 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
故事和你913 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论