0
点赞
收藏
分享

微信扫一扫

争议不断:金额到底是用Long还是BigDecimal?

先问个问题,在开发过程中你是选择用Long还是BigDecimal来处理金额?

浮点数陷阱

为什么排除float和double

浮点数无法精确表示许多十进制数。

争议不断:金额到底是用Long还是BigDecimal?_精度问题

我们希望输出0.3,但由于浮点数的表示问题,实际结果却是0.30000000000000004,这在财务计算中是要命的。

Long的利与弊

Long对于不需要小数的场景,比如计数器、库存数量等,Long是理想的选择。

精度问题

先看个例子:

争议不断:金额到底是用Long还是BigDecimal?_精度问题_02

Long为了表示小数,通常会乘以一个固定的基数(如100或10000),然后使用Long来存储。

上面的例子看起来没有问题,but 在处理更复杂的运算时,精度问题可能会显现。

比如下面这样,当涉及到除法或需要精确的舍入时:

public class LongPrecisionIssue {
    public static void main(String[] args) {
        // 表示100.05元和200.10元,转换为以分为单位的整数
        long amount1 = 10005;
        long amount2 = 20010;
        
        // 除法运算(错误示例)
        long result = amount2 / amount1;
        System.out.println("Division Result: " + result); // 输出2,实际需要更精确的小数结果
        
        // 舍入问题(错误示例)
        long partialAmount = 3333; // 表示33.33元
        long incorrectRounding = partialAmount / 3;
        System.out.println("Incorrect Rounding: " + (incorrectRounding / 100.0)); // 输出11.11,而实际应为11.11~(更精确的结果)
    }
}

Long适用于对精度要求不高且涉及大量整数运算的场景,比如计数、库存管理等。

但在涉及金融和需要精确小数的计算中,Long就显得力不从心了。

BigDecimal的高精度世界

BigDecimal提供了任意精度的运算能力,能够精确控制舍入行为,非常适合金融计算。

争议不断:金额到底是用Long还是BigDecimal?_浮点数_03

舍入控制

BigDecimal允许我们精确控制舍入方式,例如HALF_UP(四舍五入),这在金融计算中尤为重要。

争议不断:金额到底是用Long还是BigDecimal?_浮点数_04

缺点

尽管BigDecimal在精度和功能上优势明显,但它在性能和使用复杂性上有所牺牲。

因为每次运算都会创建新的BigDecimal对象,无形中增加了内存开销和GC压力。

实践案例

在实际开发中,还是建议使用BigDecimal来确保金额计算的精确性。

特别是在金融和电商等对金额精度要求高的场景中,BigDecimal几乎是必选项。

以下是一个简单的银行交易系统示例,展示如何使用BigDecimal进行精确的金额计算:

争议不断:金额到底是用Long还是BigDecimal?_金融计算_05

第三方建议

阿里巴巴开发手册是建议使用Long来存储金额的整数部分,同时在应用层进行金额的格式化和计算,这种方法适用于业务逻辑较简单的场景。

MySQL官方推荐使用DECIMAL类型来存储金额,以确保存储和计算的精度,DECIMAL类型不仅可以表示精确的小数,还可以避免浮点数表示问题。

如果你的业务场景对金额的精度要求非常高,BigDecimal是首选;

如果是对整数金额进行处理,可以考虑使用Long。

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。


举报

相关推荐

0 条评论