Java使用BigDecimal(公式精确计算)+(精度丢失问题)

简介: Java使用BigDecimal(公式精确计算)+(精度丢失问题)

一、Java使用BigDecimal公式计算(精确计算)

介绍:

      使用BigDecimal加减乘除方法运算,可以使用BigDecimal类提供的add、subtract、multiply、divide方法函数实现。

公式加法计算~add

  public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       //BigDecimal计算add
       BigDecimal addResult = a.add(b);
       System.out.println("结果集: " +addResult);
   }

结果集:

97ffaff1e8574d39bc9c4e0867d3870d.png

公式减法计算~subtract

public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       BigDecimal计算subtract
       BigDecimal subtract = a.subtract(b);
       System.out.println("结果集subtract: " +subtract);
   }

结果集:

c42b89efaeab4e9c9f1bab2e9e3d0f55.png

公式乘法计算~multiply

public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       BigDecimal计算multiply
       BigDecimal multiply = a.multiply(b);
       System.out.println("结果集: " +multiply);
   }

结果集:


a6849f83ef5f4759be0d391788eec431.png

公式除法计算~divide

public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       //BigDecimal计算divide
       //ROUND_HALF_UP:向“最接近的”整数舍入。 若舍入位大于等于5,则对舍入部分的前一位数字加1;若舍入位小于5,则直接舍弃。即为四舍五入模式。
       BigDecimal divide = a.divide(b,2,BigDecimal.ROUND_HALF_UP);//四舍五入,保留两位小数.
       System.out.println("结果集: " +divide);
   }

结果集:


d9d157214e944816bb03d4db0e26339f.png

二、 BigDecimal(舍入模式)选择

简介:

BigDecimal.setScale主要用于对BigDecimal数据小数点后的位数进行 进位、舍位、截断等操java.math.RoundingMode:这是一种枚举类型,它定义了8种数据的舍入模式。它与java.math.BigDecimal类中定义的8个同名静态常量的作用相同,可用BigDecimal.setScale(int newScale, RoundingMode roundingMode)来设置数据的精度和舍入模式。


1、ROUND_UP:向远离零的方向舍入。


       若舍入位为非零,则对舍入部分的前一位数字加1;若舍入位为零,则直接舍弃。即为向外取整模式。


2、ROUND_DOWN:向接近零的方向舍入。


       不论舍入位是否为零,都直接舍弃。即为向内取整模式。


3、ROUND_CEILING:向正无穷大的方向舍入。


       若 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;若为负,则舍入行为与 ROUND_DOWN 相同。即为向上取整模式。


4、ROUND_FLOOR:向负无穷大的方向舍入。


       若 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;若为负,则舍入行为与 ROUND_UP 相同。即为向下取整模式。


5、ROUND_HALF_UP:向“最接近的”整数舍入。


       若舍入位大于等于5,则对舍入部分的前一位数字加1;若舍入位小于5,则直接舍弃。即为四舍五入模式。


6、ROUND_HALF_DOWN:向“最接近的”整数舍入。


       若舍入位大于5,则对舍入部分的前一位数字加1;若舍入位小于等于5,则直接舍弃。即为五舍六入模式。


7、ROUND_HALF_EVEN:向“最接近的”整数舍入。


       若(舍入位大于5)或者(舍入位等于5且前一位为奇数),则对舍入部分的前一位数字加1;


       若(舍入位小于5)或者(舍入位等于5且前一位为偶数),则直接舍弃。即为银行家舍入模式。


8、ROUND_UNNECESSARY


       断言请求的操作具有精确的结果,因此不需要舍入。


       如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。


案例:  

 public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       //BigDecimal计算divide
       //ROUND_HALF_UP:向“最接近的”整数舍入。 若舍入位大于等于5,则对舍入部分的前一位数字加1;若舍入位小于5,则直接舍弃。即为四舍五入模式。
       //ROUND_UP:向远离零的方向舍入。  若舍入位为非零,则对舍入部分的前一位数字加1;若舍入位为零,则直接舍弃。即为向外取整模式。
       BigDecimal divide = a.divide(b,BigDecimal.ROUND_HALF_UP, 2).setScale(2,ROUND_UP);
       System.out.println("结果集: " +divide);
   }

结果集:

b97b10e10a4a456e8604e15a4e7a828d.png

计算器结果集如下图:


85e7f8f20bd14e0fbe6af420fac400c3.png

三、 BigDecimal.setScale用法案例

BigDecimal.setScale主要用于对BigDecimal数据小数点后的位数进行 进位、舍位、截断等操作

public  static void main(String[] args){
       BigDecimal a = BigDecimal.valueOf(5.6);
       BigDecimal b = BigDecimal.valueOf(2.1);
       //BigDecimal计算divide
       BigDecimal divide = a.divide(b,2,BigDecimal.ROUND_UP).setScale(2, BigDecimal.ROUND_UP);
       System.out.println("结果集: " +divide);
   }

结果集:


04d09b56f338495d80991bd53a8e97ed.png

四、Java介绍:

在实际应用中,经常会使用到计算,举例如 '银行' 特别是在我们交易的时候,计算结果要求的更加精确,这个时候我们就会使用到java.math包中提供的API类BigDecimal,用于对超过16位有效位数的数字进行精确的计算。

以如下代码为例:

使用BigDecimal精度丢失问题

public  static void main(String[] args){
       System.out.println("使用bigDecimal进行转换"+new BigDecimal(234.567));
   }

运行后结果集出现精度丢失:


afb904bca99f4296a0da0ed800c558f4.png


结果可以看出使用new BigDecimal(234.567),传入参数为double类型发生精度丢失,运行的结果并不等于234.567,而是为234.5670000000000072759576141834259033203125。


原因是double不能表示为任何有限长度的二进制小数;


解决方法:     使用new BigDecimal(String)构造函数,创建一个参数以字符串表示数值的对象

public  static void main(String[] args){
       double a = 234.567;
       String  b = "234.567";
       // 方式一:double的封装类Double中的toString()方法解决
       System.out.println("使用bigDecimal进行转换" + new BigDecimal(new Double(a).toString()));
       // 方式二:使用String接收数值
       System.out.println("使用bigDecimal进行转换" + new BigDecimal(b));
   }

结果集如下:


961eea57f0b745fb9e9857a8e1745bb8.png


如需使用加减乘除方法运算,可以使用BigDecimal类提供的add、subtract、multiply、divide方法实现 如上:Java使用BigDecimal公式计算。

目录
相关文章
|
21天前
|
Java
Java项目中高精度数值计算:为何BigDecimal优于Double
在Java项目开发中,涉及金额计算、面积计算等高精度数值操作时,应选择 `BigDecimal` 而非 `Double`。`BigDecimal` 提供任意精度的小数运算、多种舍入模式和良好的可读性,确保计算结果的准确性和可靠性。例如,在金额计算中,`BigDecimal` 可以精确到小数点后两位,而 `Double` 可能因精度问题导致结果不准确。
|
4月前
|
Java
【Java】Math、System、RunTime、BigDecimal类常用方法
【Java】Math、System、RunTime、BigDecimal类常用方法
|
1月前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
57 2
|
1月前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
2月前
|
安全 Java
java BigDecimal 的赋值一个常量
在 Java 中,`BigDecimal` 是一个用于精确计算的类,特别适合处理需要高精度和小数点运算的场景。如果你需要给 `BigDecimal` 赋值一个常量,可以使用其静态方法 `valueOf` 或者直接通过字符串构造函数。 以下是几种常见的方法来给 `BigDecimal` 赋值一个常量: ### 使用 `BigDecimal.valueOf` 这是推荐的方式,因为它可以避免潜在的精度问题。 ```java import java.math.BigDecimal; public class BigDecimalExample { public static void
|
2月前
|
机器学习/深度学习 算法 搜索推荐
让星星⭐月亮告诉你,Java冒泡排序及其时间复杂度计算
冒泡排序是一种简单的排序算法,通过多次遍历数组,每次比较相邻元素并交换位置,将较小的元素逐步移至数组前端。第一轮结束后,最小值会位于首位;第二轮则将次小值置于第二位,依此类推。经过 (n-1) 轮遍历后,数组完成排序。冒泡排序的时间复杂度为 O(n²),在最优情况下(已排序数组)时间复杂度为 O(n)。示例代码展示了如何实现冒泡排序。
56 1
|
2月前
|
分布式计算 资源调度 Hadoop
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
Hadoop-10-HDFS集群 Java实现MapReduce WordCount计算 Hadoop序列化 编写Mapper和Reducer和Driver 附带POM 详细代码 图文等内容
104 3
|
1月前
|
Java API Apache
java集合的组内平均值怎么计算
通过本文的介绍,我们了解了在Java中计算集合的组内平均值的几种方法。每种方法都有其优缺点,具体选择哪种方法应根据实际需求和场景决定。无论是使用传统的循环方法,还是利用Java 8的Stream API,亦或是使用第三方库(如Apache Commons Collections和Guava),都可以有效地计算集合的组内平均值。希望本文对您理解和实现Java中的集合平均值计算有所帮助。
36 0
|
2月前
|
消息中间件 Java Kafka
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
Flink-04 Flink Java 3分钟上手 FlinkKafkaConsumer消费Kafka数据 进行计算SingleOutputStreamOperatorDataStreamSource
54 1
|
4月前
|
存储 Java API
"揭秘!为何BigDecimal成为精准计算的守护神?告别浮点数误差,让每一分钱都精准无误!"
【8月更文挑战第11天】在编程中处理金融或科学计算时,常遇浮点数运算精度丢失问题。Java的`double`和`float`虽能覆盖广泛数值范围,但在特定小数运算上力有未逮。`BigDecimal`则以其独特的设计确保了精度。它位于`java.math`包内,通过`BigInteger`存储数值绝对值及`scale`表示小数位数,从而精确表示任意精度的小数。
67 4
下一篇
DataWorks