news 2026/6/6 12:00:00

金额能不能用浮点数类型去存储?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
金额能不能用浮点数类型去存储?

💡 核心结论:一句话先记住

计算机用二进制算十进制小数会“脑抽”!0.10.2这种简单的小数,在计算机底层其实是无限循环小数。如果你图省事用floatdouble存钱,算着算着钱就会悄悄蒸发或者凭空变多,日终对账财务绝对会跟你拼命。


🛑 翻车现场:浮点数算钱有多离谱?

我们直接看代码,用事实说话。在 Java 中执行以下操作,结果会让你怀疑人生:

publicclassFloatMoneyDemo{publicstaticvoidmain(String[]args){// 案例 1:0.1 + 0.2 居然不等于 0.3doublea=0.1;doubleb=0.2;System.out.println("0.1 + 0.2 = "+(a+b));// ❌ 实际输出: 0.30000000000000004System.out.println(a+b==0.3);// ❌ 输出: false// 案例 2:每天存一毛钱,存10天doubletotal=0.0;for(inti=0;i<10;i++){total+=0.1;}System.out.println("加了10次0.1: "+total);// ❌ 实际输出: 0.9999999999999999(不是 1.0!)// 案例 3:商品单价 19.9 元,买 3 件doubleprice=19.9;intcount=3;System.out.println("19.9 * 3 = "+(price*count));// ❌ 实际输出: 59.699999999999996}}

原因其实很简单:计算机用的是IEEE 754标准,只有分母是 2 的幂次(比如 0.5, 0.25)的小数才能被精确转换成二进制。其他的数字都会被无情截断,单次误差虽然小,但大量累加或做乘除法时,误差就会被无限放大


🛠️ 正确的替代方案(怎么抄作业?)

在金融或者电商系统中,正确的数钱姿势只有以下两种:

方式一:使用BigDecimal(官方高精度推荐 ⭐⭐⭐⭐⭐)

这是 Java 官方专门写出来应付高精度计算的“数学大师”。只要你用对了姿势,它绝对不会错一分钱。

⚠️死脑筋警告:千万别用new BigDecimal(0.1),传入 double 的那一刻精度就已经脏了!必须用字符串构造new BigDecimal("0.1")

💻 代码展示:
importjava.math.BigDecimal;importjava.math.RoundingMode;publicclassBigDecimalMoneyDemo{publicstaticvoidmain(String[]args){// ✅ 正确姿势:必须使用字符串(String)构造BigDecimala=newBigDecimal("0.1");BigDecimalb=newBigDecimal("0.2");BigDecimalresult=a.add(b);System.out.println("正确加法结果: "+result);// 输出: 0.3// ⚠️ 注意点 1:比较大小要用 compareTo(),绝对不能用 equals()!// 因为 equals 会连带小数点后的位数(精度)一起比,1.0 和 1.00 会返回 false。System.out.println("比较结果: "+(result.compareTo(newBigDecimal("0.3"))==0));// 输出: true// ⚠️ 注意点 2:做乘除法时,必须指定保留几位小数和“舍入模式”(比如四舍五入)// 否则遇到 10/3 这种除不尽的情况,系统会直接抛出异常(ArithmeticException)卡死。BigDecimalprice=newBigDecimal("19.9");BigDecimalcount=newBigDecimal("3");// 算总价,保留2位小数,四舍五入BigDecimaltotal=price.multiply(count).setScale(2,RoundingMode.HALF_UP);System.out.println("正确的商品总价: "+total);// 输出: 59.70}}

方式二:把单位换成“分”,全程用long(高性能极客推荐 ⭐⭐⭐⭐)

既然小数不靠谱,那我们直接把小数消灭掉!1元=100分。系统里所有的账目全部以“分”为单位存成整数(long类型),算完之后,只有在展示给用户看的时候再除以 100 变成“元”。

  • 优势:纯整数运算,速度飞快,内存占用极小。
  • 劣势:不适合算利息这种需要超多小数位的复杂金融场景。
💻 代码展示:
publicclassLongMoneyDemo{publicstaticvoidmain(String[]args){// 19.90 元在系统里直接存成 1990 分longpriceInCents=1990;intcount=3;// 全程整数乘法,稳如老狗,绝对不会丢失精度longtotalInCents=priceInCents*count;System.out.println("总价(分): "+totalInCents);// 输出: 5970// 只有在最后页面展示、打印发票时,再临时转成“元”doubletotalInYuan=totalInCents/100.0;System.out.println("前端展示总价(元): "+totalInYuan);// 输出: 59.7}}

🗄️ 数据库里面怎么存?

代码改好了,数据库字段也别踩坑:

  • 如果用方式一:MySQL 字段类型请选择DECIMAL(19, 4)(表示总共19位,小数点后保留4位),严禁使用 float/double
  • 如果用方式二:MySQL 字段类型请直接选择BIGINT(直接存整数“分”)。

🎯 终极秒记口诀

浮点存金额,精度必丢失;BigD 用字符串,除法指定舍;或者用长整,单位换成分!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 11:56:50

IT培训招生新范式落地全记录(CSDN AI+私域转化SOP深度拆解)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;IT培训机构能用 CSDN AI 数字营销做招生引流吗&#xff1f; CSDN AI 数字营销平台依托其技术社区流量、AI 内容生成与用户行为建模能力&#xff0c;为 IT 培训机构提供了低成本、高精度的招生引流新路径…

作者头像 李华
网站建设 2026/6/6 11:55:42

VCS混合仿真避坑指南:从synopsys_sim.setup到Makefile,这些细节别踩雷

VCS混合仿真避坑指南&#xff1a;从synopsys_sim.setup到Makefile的深度优化在芯片设计验证领域&#xff0c;混合语言仿真一直是工程师们又爱又恨的技术。当你同时面对VHDL的严谨和Verilog的灵活时&#xff0c;VCS作为业界主流的仿真工具&#xff0c;其混合仿真能力虽然强大&am…

作者头像 李华
网站建设 2026/6/6 11:54:30

Keyviz:终极键盘鼠标可视化神器,让你的操作一目了然!

Keyviz&#xff1a;终极键盘鼠标可视化神器&#xff0c;让你的操作一目了然&#xff01; 【免费下载链接】keyviz Keyviz is a free and open-source tool to visualize your keystrokes ⌨️ and &#x1f5b1;️ mouse actions in real-time. 项目地址: https://gitcode.co…

作者头像 李华