Code Ease Code Ease
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档

神秘的鱼仔

你会累是因为你在走上坡路
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档
服务器
  • Java核心基础

  • 框架的艺术

  • 分布式与微服务

  • 开发经验大全

    • 如何用Java写一个规范的http接口?
    • 一个成熟的Java项目如何优雅地处理异常
    • 项目经理最近感觉系统慢了,想知道整个系统每个方法的执行时间
    • 财务说账单上少了一分钱,老板看到代码气疯了
      • (一)前言
      • (二)Java中如何处理金额
      • (三)Mysql中如何存储金额
      • (四)总结
    • 浅析五种最常用的Java加密算法,以后可以直接拿来用了
    • 你真的会用idea进行debug吗?idea实用debug教程
    • 还不知道项目中怎么写日志?slf4j+log4j帮你搞定!
    • 如何在工作中快速上手Git
    • 号称"最强API文档工具"的Swagger到底厉害在哪
    • 分享工作一年后收藏的超好用Idea插件,工作效率直接翻倍
    • 怎样才能写出规范的好代码?
    • 如何上传自己的jar包到maven中央仓库(2021最新版)
    • 使用Optional更优雅地处理非空判断
    • 查准考证网站卡了整整一个小时进不去,被抢票支配的恐惧又来了
    • 线上报了内存溢出异常,又不完全是内存溢出
  • 版本新特性

  • Java
  • 开发经验大全
CodeEase
2023-10-24
目录

财务说账单上少了一分钱,老板看到代码气疯了

作者:鱼仔
博客首页: codeease.top (opens new window)
公众号:Java鱼仔

# (一)前言

在刚学Java的时候,我们老师就和我们说float和double的精度是存在误差的,原因在于二进制中没有准确表示比如0.1,0.00001这样的数据,甚至于操作系统的位数也会影响到float和double的精度。刚好前几天遇到了这样一个问题,一个财务对接系统反馈金额账上对应不上,检查历史代码后发现竟然有人用float去修饰了金额,导致计算后精度误差。

    public static void main(String[] args) {
        float a=50.49f;
        System.out.println(a);
        System.out.println(a*10);
    }
1
2
3
4
5

比如这段代码,结果是:

50.49
504.90002
1
2

这已经是很低级的错误了。

# (二)Java中如何处理金额

Java中提供了一个类BigDecmal来进行精确计算,BigDecmal中提供了多种构造方法,但是如果是金额相关数据,建议一定要使用String来构造。

    public static void main(String[] args) {
        float a=50.49f;
        String a2=String.valueOf(a);
        BigDecimal bigDecimal=new BigDecimal(a);
        System.out.println(bigDecimal);  //输出50.490001678466796875
        BigDecimal bigDecimal2=new BigDecimal(a2);
        System.out.println(bigDecimal2); //输出50.49
    }
1
2
3
4
5
6
7
8

原因通过代码就可以看出来了,使用float构造方法,转换出来的数据依旧是不精确的。

BigDecimal的操作最常用的就是加减乘除,他也提供了这一系列的方法:

    public static void main(String[] args) {
        BigDecimal bigDecimal=new BigDecimal("50.49");
        System.out.println(bigDecimal);
        System.out.println(bigDecimal.add(new BigDecimal("10")));  //加
        System.out.println(bigDecimal.subtract(new BigDecimal("10")));  //减
        System.out.println(bigDecimal.multiply(new BigDecimal("10")));  //乘
        System.out.println(bigDecimal.divide(new BigDecimal("10")));  //除
    }
1
2
3
4
5
6
7
8

有关BigDecimal的更多操作可以查阅官方文档。

除了使用BigDecimal之外,还可以换个思路。比如一个金额如果需要保留两位小数,那么我们就可以在计算时按分来计算,比如100元就是10000分,这个10000分是整型。不过还是建议使用BigDecimal。

# (三)Mysql中如何存储金额

在Mysql中,可以用decimal字段记录金额:

`money` DECIMAL(18,2) not null comment '金额'
1

同时也能用varchar以字符串的方式保存

或者通过int或者bigint来存储以分为单位的金额。

具体如何选择,还是要看项目中如何使用。

# (四)总结

总结一句,凡是代码中和钱打交道的业务,务必要小心谨慎,多测试几遍。不然出事情之后很难收尾。我是鱼仔,我们下期再见!

上次更新: 2025/02/18, 11:30:08
项目经理最近感觉系统慢了,想知道整个系统每个方法的执行时间
浅析五种最常用的Java加密算法,以后可以直接拿来用了

← 项目经理最近感觉系统慢了,想知道整个系统每个方法的执行时间 浅析五种最常用的Java加密算法,以后可以直接拿来用了→

最近更新
01
AI大模型部署指南
02-18
02
半个月了,DeepSeek为什么还是服务不可用
02-13
03
Python3.9及3.10安装文档
01-23
更多文章>
Theme by Vdoing | Copyright © 2023-2025 备案图标 浙公网安备33021202002405 | 浙ICP备2023040452号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式