Java小白踩坑录 - 一分钱到底去哪里了?

简介: Java小白踩坑录 - 一分钱到底去哪里了?

image.png

客户每次下单扣款后金额都对不上,为了不泄露公司密码,将程序简化一下:

public static void main(String[] args) {    
  double total=2.00f;
  double cost=1.10f;
  System.out.println(total-cost);
}

小白测试了好多次,每次的结果都和预期不一致,就有点懵逼了。

结果是:

0.8999999761581421

涉及到金额,不正确可不行!

寻找门路

碰到问题,网上找。小白赶紧找人问,网上千篇一律的都告诉他,交易计算时使用 BigDecimal 不要使用 double,赶紧解决问题吧。

public static void main(String[] args) {
        BigDecimal total=new BigDecimal(2.00);
        BigDecimal cost=new BigDecimal(1.10);
        System.out.println(total.subtract(cost));
}

运行结果:

0.899999999999999911182158029987476766109466552734375

这网上也太不靠谱了吧?

求助Leader

折腾了半天,问题并没有解决,小白慌了,这种 bug 的工作量一般是一天,如果再不解决,测试 MM 就要催死了,于是向小 L 求救,小 L 只看了小白的代码一眼,敲了一下键盘,小白眼一花,结果就正确了。

public static void main(String[] args) {
    BigDecimal total=new BigDecimal("2.00");
    BigDecimal cost=new BigDecimal("1.10");
    System.out.println(total.subtract(cost));
}

输出结果:

0.90

小白看傻了!

小白:“等等!我们的程序不是一样的吗?为什么你的可以得出正确的结果,而我的是错误的?”

小L

BigDecimal total=new BigDecimal(2.00);
BigDecimal cost=new BigDecimal(1.10);

是将 double 值传入 BigDecimal 实例里,double 本身会损失精度,故结果也会损失精度;而使用

BigDecimal total=new BigDecimal("2.00");
BigDecimal cost=new BigDecimal("1.10");

BigDecimal 实例 total 和 cost 会解析字符串的值,不会损失精度。详细实现你可以看 BigDecimal 的源码”

小白:“好的,那我就提交代码,让测试 MM 测试了。”

小L:“且慢,这段程序会出现什么问题?有没有更好的办法?”

小白:“网上大家都是这么用的,应该没有问题。”

小L:“在我们公司的业务中,下单扣款接口比较重要,调用量也高,使用 BigDecimal 会出现什么问题吗?”

小白:“会影响计算性能,导致 cpu 升高,进而影响接口的性能。”

小L:“你的计算机功底不错,那我们该如何解决呢?”

小白:“能否给我一点提示呢?”

小L:“在现实生活中,我们的金额计算是不是最小为分,没有更小的货币了,可以从这方面考虑!”

小白:“我懂了,在我们的业务中可以使用 int 结算,毕竟总额和消费金额及余额最小单位为分,可以使用 int 计算出。”

小L:“总之, 在需要精确答案的地方,要避免使用 float 和 double;对于货币计算,要使用 int、long 或 BigDecimal,同时也要考虑业务的本身的使用场景,选择合适的数据类型。”


问题解决

向小 L 请教之后,小白的思路清晰起来,迅速修改程序,提交并打包交给测试 M 进行测试,最后圆满通过所有用例。

public static void main(String[] args) {        
    int total=200;
    int cost=110;
    System.out.println((200-110)+" cents");
}

通过这件事情之后,小白端正了自己的态度,学习了以下几点:

  1. Java 基础不够扎实,需要进一步加强;
  2. 不同的业务场景,程序可能不一样,需要因地制宜。
目录
相关文章
|
算法 程序员 Shell
python股票量化交易(11)---使用pyqt5构建股票交易软件主页
python股票量化交易(11)---使用pyqt5构建股票交易软件主页
1245 0
python股票量化交易(11)---使用pyqt5构建股票交易软件主页
|
Python
python股票量化交易(14)---使用pyqt5构建股票交易龙虎榜
python股票量化交易(14)---使用pyqt5构建股票交易龙虎榜
797 0
python股票量化交易(14)---使用pyqt5构建股票交易龙虎榜
|
21小时前
|
云安全 人工智能 自然语言处理
|
5天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
314 116
|
8天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
554 51
Meta SAM3开源:让图像分割,听懂你的话
|
20天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
|
4天前
|
弹性计算 人工智能 Cloud Native
阿里云无门槛和有门槛优惠券解析:学生券,满减券,补贴券等优惠券领取与使用介绍
为了回馈用户与助力更多用户节省上云成本,阿里云会经常推出各种优惠券相关的活动,包括无门槛优惠券和有门槛优惠券。本文将详细介绍阿里云无门槛优惠券的领取与使用方式,同时也会概述几种常见的有门槛优惠券,帮助用户更好地利用这些优惠,降低云服务的成本。
264 132