金融类应用数字运算的建议

本文讨论了金融应用中遇到的精度丢失问题,主要集中在double类型的浮点运算。提出了两个最佳实践:1) 设计阶段即以长整型long处理金额,避免浮点类型;2) 如果无法修改后台,可以通过String接收浮点数并转化为BigDecimal进行精确计算。解释了为何不能直接使用double构造BigDecimal,并分析了浮点数在二进制表示下的精度问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遇到问题,精度丢失

最近一年多的时间一直在做智能POS相关的应用,经常涉及到金额的运算.后台金额是按照元为单位保留两位小数的浮点类型,我在客户端接收的时候也是按照double类型保存的.后来在运算的时候发现了好多时候会出现精度丢失的情况.经过我研究最后总结了两个最佳实践.

最佳实践1

一句话,不用浮点类型.(long的取值范围为-9223372036854775808到9223372036854775807,一般能足够满足您对金额的需求)
若您的项目现在处在设计阶段,建议后台设计的时候就以分为单位,用长整形long返回接收,这样就能避免一系列的浮点类型进行运算产生的精度丢失问题.在页面上需要展示价格的时候转换成BigDecimal做运算设置保留两位小数即可:

long a=3680;
BigDecimal bigDecimal = new BigDecimal(a).setScale(2,BigDecimal.ROUND_HALF_UP)//ROUND_HALF_UP 四舍五入
		.divide(new BigDecimal(100));
System.out.println(bigDecimal.toPlainString());
//以下描述均为JavaApi文档描述
System.out.println(new BigDecimal("1E14").toString());//返回此 BigDecimal 的字符串表示形式,如果需要指数,则使用科学记数法。
System.out.println(new BigDecimal("1E14").toPlainString());//返回不带指数字段的此 BigDecimal 的字符串表示形式。
System.out.println(new BigDecimal("1E14").toEngineeringString());//返回此 BigDecimal 的字符串表示形式,需要指数时,则使用工程计数法。
输出结果:
36.80
1E+14
100000000000000
100E+12

最佳实践2

若后台已经不方便修改,我们可以在json接收的时候以String的形式接收后台返回的浮点类型(重点,以String类型接收浮点变量).在用到计算的时候把string装换成BigDecimal运算,运算之后输出是转换成对应的格式即可.
有人可能会问BigDecimal的构造方法不是可以穿double类型吗,为什么要用string接收?原因就是double书本身就不是精确表示的,即使转换成BigDecimal也是不准确的,所以只能用BigDecimal里String类型的构造方法.如果使用double接收也可以使用Double.toString转换为字符串再转换成BigDecimal。看下下面两个例子就能看出来了

double a =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬_小彬

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值