金融系统中正确的金额计算及存储方式
昨天微信群里在讨论金额计算及存储的话题,今天特来结贴一下。
经典的精度丢失问题
Java中的类型float、double用来做计算会有精度丢失问题,下面来看下面的示例。
1 | public static void main(String[] args) { |
上面的程序输出结果是多少?
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。
BigDecimal适合更精度的运算,也提供了丰富的操作符类型,小数位控制,四舍五入规则等。
不过,使用BigDecimal不当也有精度丢失的情况,如double的构造方法:
1 | BigDecimal(double val) |
再来看这个示例:
1 | private static void test2() { |
输出:
1 | 0.0699999999999999962529972918900966760702431201934814453125 |
这个精度就更恐怖了。。
所以,一定要使用String的构造方法:
1 | BigDecimal(String val) |
1 | private static void test3() { |
总结
金额运算尽量使用BigDecimal(String val)进行运算。
数据库存储金额,一般有整型和浮点型两种存储方式。如果是有汇率转换的,建议使用浮点数decimal进行存储,可以灵活的控制精度,decimal直接对应java类型BigDecimal。当然,用整数存储分这种形式也可以,转账的时候单位为元而如果忘了转换分为元,那就悲剧了。
推荐阅读
每个Java程序员必备的8个开发工具
本文由码农网 –王国峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!现在有很多库、实用工具和程序任J...
Java实战之医院管理系统的实现
目录项目介绍环境需要技术栈使用说明效果图展示核心代码用户管理控制层医生管理控制层病房管理控制层项目介绍医院管理系统,分为管理员、医...
elasticsearch索引index之Translog数据功能分析
目录translog的结构及写入方式translogFile的继承关系TranslogFile快照的方法总结translog的结构...
java实现简单发送邮件功能
Java实现图片比率缩放
Java中的JetCache 实战
elasticsearch索引index之engine读写控制结构实现
目录engine的实现结构Engine类的方法:如index方法的实现:总结engine的实现结构elasticsearch对于...
elasticsearch索引index之Mapping实现关系结构示例
目录Mapping的实现关系结构Mapper的三类parse方法部分Field总结Mapping的实现关系结构Lucene索引的...
LeetCode 动态规划之矩阵区域和详情
目录题目题解解题分析解题代码题目矩阵区域和给你一个mxn的矩阵mat和一个整数k,请你返回一个矩阵answer,其中每个a...
elasticsearch索引的创建过程index create逻辑分析
目录索引的创建过程materOperation方法实现clusterservice处理建立索引修改配置总结索引的创建过程从本篇...