开发过程中,我们在接触到关于金额的计算时,通常都会进行非常的精确的计算。
举例 123456.789 元,拆解为如下表格所示
1 | 2 | 3 | 4 | 5 | 6 | . | 7 | 8 | 9 |
十万 | 万 | 千 | 百 | 十 | 个 | 小数点位 | 角 | 分 | 厘 |
通常精确到分,也有到厘的,但很少,所以本篇就以精确到分为例来说明。
数据库存储金额时,通常也是使用的 "decimal"、"float"等高精度类型。
而我们在开发时,从数据库中查到 "decimal"、"float" 数据类型的数据,通常都是使用 double 类型或 decimal 、bigdecimal 类型。
经过查询之后,通常会将金额进行格式化,例如100元要格式化显示为100.00元;50.5元要格式化显示为50.50元;不足的要补零。
格式化的方式很简单,Java 提供了现成的格式化 API 供我们使用。如下所示
public static void main(String[] args) throws ParseException {//Float value1 = 123456.789f;// double value1 = 123456.789;BigDecimal value1 = new BigDecimal("123456.789");// 创建格式化对象。0代表小数点后一位;00就是小数点后两位;000代表小数点后三位DecimalFormat df = new DecimalFormat("#.00");// 调用 format 格式化方法格式化为小数点后两位,// 注意该方法返回一个字符串,不能直接得到对应的包装类,需要调用对应的构造方法传入字符串String valueFormat = df.format(value1);// 使用Float接收格式化的金额Float aFloat = new Float(valueFormat);// 使用 Double 接收接收格式化的金额Double aDouble = new Double(valueFormat);// 使用BigDecimal接收格式化的金额BigDecimal bDecimal = new BigDecimal(valueFormat);// 打印输出System.out.println(aFloat);System.out.println(aDouble);System.out.println(bDecimal);}
我在本地测试的时候发现
(1)float 和 bigdecimal 都是四舍五入,即小数点第三位 <= 4则直接舍弃,>= 5 会向前进一;
(2)而 double 则是 五舍六入,即小数点第三位 <= 5 则直接舍弃,>= 6 会向前进一;
我不清楚是不是我JDK版本的问题,但感觉大概率是JDK版本问题。所以将代码粘贴出来供小伙伴们自行测试,动动小手也会记得会更牢固哦!
在实际的开发过程中,通常业务逻辑都是下面这样的,
// 查询数据库返回的实体 或者 前端传到后端的对象实体xxxPOJO xxx = xxxDao.selectByXXX("查询条件") 或 xxxVo.getXXX();// 通过实体获取高精字段值,建议 double 或者 bigdecimalDouble value = xxx.getXXX() 或 BigDecimal value = xxx.getXXX();// 根据业务需要选择格式化小数点后几位DecimalFormat df = new DecimalFormat("#.00");String valueFormat = df.format(value);BigDecimal decimalValue = new Float(valueFormat);// 将格式化之后的数据再放回对象中插入数据库或返回到前端xxx.setXXX(decimalValue);
如果说在项目中使用多个比较频繁,还可以定义成 static 静态方法放到 utils 工具类中供全局调用;
// 返回 BigDecimal 类型数据public static BigDecimal retNumber(BigDecimal bigDecimal){DecimalFormat df = new DecimalFormat("#.00");String decimalFormat = df.format(bigDecimal);return new BigDecimal(decimalFormat);}// 返回 Double 类型数据public static Double retNumber(Double aDouble){DecimalFormat df = new DecimalFormat("#.00");String doubleFormat = df.format(aDouble);return new Double(doubleFormat);}