使用BigDecimal(在java中怎么计算货币值)

本文对比了使用Double和BigDecimal进行货币计算的区别。通过实例演示了Double类型在货币计算中的不准确性,并推荐使用BigDecimal来确保计算的精度。适用于金融及电子商务等场景。

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

货币值会经常在金融或电子商务项目中使用。当你处理货币值的时候,经常会面临一个问题——应该用Double还是Float来代表货币的值?
答案是:应该使用java.math.BigDeciaml来代表货币值。

1.货币值 ——Double

这里有一个例子。里面用到了Double来代表货币值,看看会有什么问题。
MoneyDouble.java

package com.mkyong.test;

public class MoneyDouble {

    public static void main(String[] argv) {

        System.out.println("--- Normal Print-----");
        System.out.println(2.00 - 1.1);
        System.out.println(2.00 - 1.2);
        System.out.println(2.00 - 1.3);
        System.out.println(2.00 - 1.4);
        System.out.println(2.00 - 1.5);
        System.out.println(2.00 - 1.6);
        System.out.println(2.00 - 1.7);
        System.out.println(2.00 - 1.8);
        System.out.println(2.00 - 1.9);
        System.out.println(2.00 - 2);
        System.out.println(10.00 * 0.0825);
    }

}

输出——对于所有的Double类型的小数点,计算不够精确

--- Normal Print-----
0.8999999999999999
0.8
0.7
0.6000000000000001
0.5
0.3999999999999999
0.30000000000000004
0.19999999999999996
0.10000000000000009
0.0
0.8250000000000001

货币值——BigDecimal

为了避免上面小数点的问题,可以使用BigDecimal来代表货币值。
MoneyBigDecimal.java

package com.mkyong.test;

import java.math.BigDecimal;

public class MoneyBigDecimal {

    public static void main(String[] argv) {

        System.out.println("--- BigDecimal-----");
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.1")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.2")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.3")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.4")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.5")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.6")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.7")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.8")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.9")));
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("2")));
    }

}

输出——BigDecimal对小数点部分执行了精确的算法。

--- BigDecimal-----
0.90
0.80
0.70
0.60
0.50
0.40
0.30
0.20
0.10
0.00

注意:
BigDecimal calculations are slower than those with primitive type calculations, which may be an issue for the mission critical calculation application. For most e-commerce applications, it should be fine.

参考资料

1,原文地址
2,BigDecimal JavaDoc
3,How to Use Java BigDecimal

### 如何在 Java使用 `BigDecimal` 保留两位小数 在 Java 中,可以通过调用 `BigDecimal` 的 `setScale` 方法来设置其精度并保留指定的小数位数。此方法允许开发者通过传入两个参数实现这一目标:第一个参数表示所需的小数位数,第二个参数则定义了舍入模式。 以下是具体实现方式: #### 使用 `setScale` 方法 可以利用 `setScale(int newScale, RoundingMode roundingMode)` 来设定小数值的精确度以及处理多余部分的方式。例如,为了保留两位小数,可采用如下代码片段[^1]: ```java import java.math.BigDecimal; import java.math.RoundingMode; public class Main { public static void main(String[] args) { BigDecimal number = new BigDecimal("123.456"); // 设置保留两位小数,并使用四舍五入模式 BigDecimal roundedNumber = number.setScale(2, RoundingMode.HALF_UP); System.out.println(roundedNumber); // 输出: 123.46 } } ``` 上述代码中的 `RoundingMode.HALF_UP` 是一种常见的舍入策略,它遵循传统的四舍五入规则[^2]。 #### 舍入模式的选择 不同的业务场景可能需要不同类型的舍入逻辑。因此,在实际应用中可以根据需求选择合适的 `RoundingMode` 枚举值。一些常用的选项包括但不限于: - **CEILING**: 总是向正无穷方向取整。 - **FLOOR**: 始终朝负无穷方向取整。 - **DOWN**: 不做任何舍入操作;直接截断多余的数字而不改变最后一位有效数字。 - **UP**: 如果存在非零尾随数字,则增加最后一个有效数字。 - **HALF_DOWN**, **HALF_EVEN**, 和 **HALF_UP**: 这些都属于半调整法的不同变体,其中最常用的是 `HALF_UP` 因为其行为类似于常规意义上的“四舍六入”。 当涉及到货币计算时特别需要注意正确地实施舍入机制以避免累积误差,正如提到的一个美分差异案例所示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值