Java的BigDecimal里方法应该这样用

简介: Java的BigDecimal里方法应该这样用

预测一下运行的结果

在运行下面的代码之前,先把自己预测的结果写下来,看看能对几个


System.out.println(BigDecimal.ZERO.equals(BigDecimal.ZERO));System.out.println(BigDecimal.ZERO.equals(new BigDecimal(0)));System.out.println(BigDecimal.ZERO.equals(new BigDecimal(0.00)));System.out.println("=====================");System.out.println(BigDecimal.ZERO.equals(new BigDecimal("0.0")));System.out.println(BigDecimal.ZERO.equals(new BigDecimal("0.00")));System.out.println("=====================");System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal(0)));System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal(0.00)));System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal("0.00")));

运行结果:



truetruetrue=====================falsefalse=====================000

BigDecimal 最佳实践

BigDecimal 是为了实现进行 double 和 long 的数值运算引入的,但是在实际使用过程中发现与预想的结果并不一样。

示例:



BigDecimal a = new BigDecimal(0.1);System.out.println("a values is:"+a);

运行结果:



a values is:0.1000000000000000055511151231257827021181583404541015625

原因请参考上篇文章:Java中的使用BigDecimal就不会丢失精度了吗?

equals 和 compareTo

比较是否相等应该使用 compareTo 来实现,而不是 equals,通过最开始的测试示例代码可以看到两者的区别

判断是否为 0

通过 BigDecimal.ZEROcompareTo 方法来实现:


System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal(0)) == 0);System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal(0.00)) == 0);System.out.println(BigDecimal.ZERO.compareTo(new BigDecimal("0.00")) == 0);

除法

通过 BigDecimaldivide 方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

需要通过对 divide 方法设置精确的小数点解决。


public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

(1)scale 小数点后几位

(2)roundingModel 保留位后面小数舍去的方式

  • BigDecimal.ROUND_DOWN 直接舍去
  • BigDecimal.ROUND_UP 直接向上进位向上取整。如:1.1处理后是2,-1.1处理后是-2。
  • BigDecimal.ROUND_HALF_UP 四舍五入

小数相关操作

当需要使用小数构造一个 BigDecimal 时,建议使用参数类型为 String 的构造函数或 BigDecimal.valueOf(double val);,源码如下,内部先做了 String 转化。


public static BigDecimal valueOf(double val) {    // Reminder: a zero double returns '0.0', so we cannot fastpath    // to use the constant ZERO.  This might be important enough to    // justify a factory approach, a cache, or a few private    // constants, later.    return new BigDecimal(Double.toString(val));}

BigDecimal 的不可变性

进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值


BigDecimal b1 = new BigDecimal("1");BigDecimal b2 = new BigDecimal("2");System.out.println(b1.add(b2));System.out.println(b1);

总结

因为在一些需要计算金钱或者财经类(股票、基金等)数据时可能使用 BigDecimal 的场景较多

  1. 在需要精确的小数计算时再使用 BigDecimal,性能比 doublefloat 差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用 BigDecimal
  2. 比较是否相等应该使用 compareTo 来实现。
  3. 通过 BigDecimaldivide 方法进行除法时,要设置保底小数位数。
  4. 尽量使用参数类型为 String 的构造函数或 BigDecimal.valueOf(double val);
  5. BigDecimal 都是不可变的,在进行每一次四则运算时,都会产生一个新的对象,所以在做加减乘除运算时要记得要保存操作后的值。

相关推荐

Java中的使用BigDecimal就不会丢失精度了吗?

如果觉得还有帮助的话,你的关注和转发是对我最大的支持,O(∩_∩)O:

相关文章
|
1月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
1月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
74 9
|
29天前
|
安全 Java 开发者
Java中WAIT和NOTIFY方法必须在同步块中调用的原因
在Java多线程编程中,`wait()`和`notify()`方法是实现线程间协作的关键。这两个方法必须在同步块或同步方法中调用,这一要求背后有着深刻的原因。本文将深入探讨为什么`wait()`和`notify()`方法必须在同步块中调用,以及这一机制如何确保线程安全和避免死锁。
41 4
|
29天前
|
Java
深入探讨Java中的中断机制:INTERRUPTED和ISINTERRUPTED方法详解
在Java多线程编程中,中断机制是协调线程行为的重要手段。了解和正确使用中断机制对于编写高效、可靠的并发程序至关重要。本文将深入探讨Java中的`Thread.interrupted()`和`Thread.isInterrupted()`方法的区别及其应用场景。
30 4
|
27天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
26 1
|
27天前
|
Java
Java项目中高精度数值计算:为何BigDecimal优于Double
在Java项目开发中,涉及金额计算、面积计算等高精度数值操作时,应选择 `BigDecimal` 而非 `Double`。`BigDecimal` 提供任意精度的小数运算、多种舍入模式和良好的可读性,确保计算结果的准确性和可靠性。例如,在金额计算中,`BigDecimal` 可以精确到小数点后两位,而 `Double` 可能因精度问题导致结果不准确。
|
2月前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
54 17
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
133 4
|
1月前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
213 2
|
2月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
25 2