• 进阶JAVA篇- BigDecimal 类的常用API(四)


    目录

    API                

            1.0 BigDecimal 类说明

            1.1 为什么浮点数会计算不精确呢?

            1.2  如何创建 BigDecimal 类型的对象

                    1.2.1具体来介绍三种方式来创建:

                    1.2.2 结合三种创建方法,一起来分析一下。 

            1.3 BigDecimal 类中的 valueOf(String str) 方法

            1.4 BigDecimal 类中的 add() 方法(加减乘除的操作都是一样的,就不多赘述了)

            1.5 BigDecimal 类中的 doubleValue() 方法


    API                

            1.0 BigDecimal 类说明

            BigDecimal 类是Java中用于精确表示大数的类,可以进行精确的数值运算。在需要精确计算的场景中,可以使用 BigDecimal 类来避免由于浮点数计算误差导致的计算结果不准确的问题。

            1.1 为什么浮点数会计算不精确呢?

    代码如下:

    1. public class Text {
    2. public static void main(String[] args) {
    3. double data1 = 0.1;
    4. double data2 = 0.2;
    5. System.out.println(data1+data2);
    6. }
    7. }

    运行代码如下:

            结果不是0.3,显然结果跟我们预想的不一样。当然不是所以的浮点数运行出来的结果都是错误的,只是有这一部分是运行出来的结果是错误的,但是这一部分我们作为合格的程序员来说是不能接收的。

              浮点数在计算机中的表示方式是通过将数值分为两部分:尾数和指数。尾数用来表示数值的有效位数,而指数用来表示数值的大小范围。然而,由于计算机内存的限制,尾数和指数都只能用有限的位数来表示,这就导致了浮点数的精度有限。

    1. 二进制表示:计算机使用二进制来表示浮点数,而大部分十进制数无法精确转换为二进制表示。例如,0.1(十进制)在二进制表示中是一个无限循环的小数0.00011001100110011...,因此在计算机中只能近似表示。

    2. 有限的位数:浮点数的尾数和指数都只能用有限的位数来表示,这就导致了浮点数的精度有限。例如,Java中的double类型只能精确表示15位有效数字,超过这个范围的数字会被截断或四舍五入。

    3. 浮点数运算误差:在进行浮点数运算时,由于尾数和指数的有限位数表示,计算机无法精确表示所有的运算结果。这就导致了浮点数运算的结果可能存在一定的误差。

    4. 舍入误差:在将一个浮点数转换为二进制表示时,可能会存在舍入误差。例如,一个无限循环的小数在转换为二进制表示时会被截断或四舍五入,从而导致精度损失。 

            1.2  如何创建 BigDecimal 类型的对象

                    1.2.1具体来介绍三种方式来创建:

    1.代码如下: 

    1. import java.math.BigDecimal;
    2. public class BigDecimalMethod1 {
    3. public static void main(String[] args) {
    4. //先定义了两个基本数据类型,我们知道
    5. //0.1 + 0.2 在double 类型运行是不精确的
    6. double data1 = 0.1;
    7. double data2 = 0.2;
    8. //由基本数据类型转变为引用类型
    9. //利用自动装箱,在等号后面可以直接写基本数据类型,它会自动装箱
    10. Double d1 = data1;
    11. Double d2 = data2;
    12. //将Double类型转变为String类型
    13. //利用Double类型实例方法toString()
    14. String s1 = d1.toString();
    15. String s2 = d2.toString();
    16. //利用构造器传进字符串来创建对象,
    17. //由字符串类型转变为BigDecimal类型
    18. BigDecimal b1 = new BigDecimal(s1);
    19. BigDecimal b2 = new BigDecimal(s2);
    20. //BigDecimal类中的实例方法 add()方法,
    21. //将两个BigDecimal类型相加
    22. BigDecimal c = b1.add(b2);
    23. //调用BigDecimal的实例方法 doubleValue(),
    24. //将BigDecimal类型转变为基本数据类型
    25. double a = c.doubleValue();
    26. //+1是为了表达a是浮点型,不是字符串
    27. System.out.println(a+1);
    28. }
    29. }

    运行结果如下:

     

     

    2.代码如下:

    1. import java.math.BigDecimal;
    2. public class BigDecimalMethod2 {
    3. public static void main(String[] args) {
    4. //先定义了两个基本数据类型,我们知道
    5. //0.1 + 0.2 在double 类型运行是不精确的
    6. double data1 = 0.1;
    7. double data2 = 0.2;
    8. //直接调用Double类中的静态方法toString(),
    9. //转变为字符串
    10. String s1 = Double.toString(data1);
    11. String s2 = Double.toString(data2);
    12. //利用有参数的构造器,传入字符串创建对象
    13. BigDecimal b1 = new BigDecimal(s1);
    14. BigDecimal b2 = new BigDecimal(s2);
    15. //BigDecimal类中的实例方法 add()方法,
    16. //将两个BigDecimal类型相加
    17. BigDecimal c = b1.add(b2);
    18. //调用BigDecimal的实例方法 doubleValue(),
    19. //将BigDecimal类型转变为基本数据类型
    20. double a = c.doubleValue();
    21. //+1是为了表达a是浮点型,不是字符串
    22. System.out.println(a + 1);
    23. }
    24. }

    运行结果如下:

     3.代码如下:

    1. import java.math.BigDecimal;
    2. public class BigDecimalMethod3 {
    3. public static void main(String[] args) {
    4. //先定义了两个基本数据类型,我们知道
    5. //0.1 + 0.2 在double 类型运行是不精确的
    6. double data1 = 0.1;
    7. double data2 = 0.2;
    8. //这个就更加直接了,直接用BigDecimal中静态方法,
    9. //将浮点数类型转变为BigDecimal类型
    10. BigDecimal b1 = BigDecimal.valueOf(data1);
    11. BigDecimal b2 = BigDecimal.valueOf(data2);
    12. //BigDecimal类中的实例方法 add()方法,
    13. //将两个BigDecimal类型相加
    14. BigDecimal c = b1.add(b2);
    15. //将BigDecimal类型转变为浮点数类型
    16. double a = c.doubleValue();
    17. //+1是为了表达a是浮点型,不是字符串
    18. System.out.println(a+1);
    19. }
    20. }

    运行代码如下:

                    1.2.2 结合三种创建方法,一起来分析一下。 

             第一种方式与第二种方式都是通过浮点型转变为字符串,然后再通过构造器转入字符串来创建BigDecimal 类型的对象,二者的区别在于有无创建Double对象,第一种是通过创建对象得到实例方法 toString() 将浮点型转变为字符串,而第二种没有创建Double对象,直接用Double类的静态方法 toString() 将浮点型转变为字符串。这两种方式的历程是由 浮点数 - 字符串 - BigDecimal类型。

            第三种是直接调用BigDecimal 类中的静态方法来创建对象,历程是 浮点数 - BigDecimal类型。事实上,第三种是第二种的封装。即JAVA中为了方便,为了效率,将第二种的长串的代码“封装”成第三种方法。

     

            1.3 BigDecimal 类中的 valueOf(String str) 方法

            通过传进字符串来创建方法,由于上面有详细讲到,就不多赘述了。

            1.4 BigDecimal 类中的 add() 方法(加减乘除的操作都是一样的,就不多赘述了)

             两个BigDecimal 类型的对象进行相加,得到总和。

    代码如下:

    1. import java.math.BigDecimal;
    2. public class Text {
    3. public static void main(String[] args) {
    4. double data1 = 0.1;
    5. double data2 = 0.2;
    6. BigDecimal b1 = BigDecimal.valueOf(data1);
    7. BigDecimal b2 = BigDecimal.valueOf(data2);
    8. BigDecimal c = b1.add(b2);
    9. System.out.println(c);
    10. }
    11. }

    运行结果:

             其他运算的方法:

                    减法 subtract(),乘法 multiply(),除法 divide()

                    其中 divide()还可以指定小数点后的几位数。

    代码如下:

    1. import java.math.BigDecimal;
    2. public class Text {
    3. public static void main(String[] args) {
    4. double data1 = 0.1;
    5. double data2 = 0.3;
    6. BigDecimal b1 = BigDecimal.valueOf(data1);
    7. BigDecimal b2 = BigDecimal.valueOf(data2);
    8. BigDecimal c = b1.divide (b2,5);
    9. System.out.println(c);
    10. }
    11. }

    运行结果:

            假如0.1/0.3 不去指定位数的时候,会报错。

    1. import java.math.BigDecimal;
    2. public class Text {
    3. public static void main(String[] args) {
    4. double data1 = 0.1;
    5. double data2 = 0.3;
    6. BigDecimal b1 = BigDecimal.valueOf(data1);
    7. BigDecimal b2 = BigDecimal.valueOf(data2);
    8. BigDecimal c = b1.divide (b2);
    9. System.out.println(c);
    10. }
    11. }

    运行结果:

            1.5 BigDecimal 类中的 doubleValue() 方法

            BigDecimal 类型转变为 double 类型。

    代码如下:

    1. import java.math.BigDecimal;
    2. public class Text {
    3. public static void main(String[] args) {
    4. double data1 = 0.1;
    5. double data2 = 0.3;
    6. BigDecimal b1 = BigDecimal.valueOf(data1);
    7. BigDecimal b2 = BigDecimal.valueOf(data2);
    8. BigDecimal c = b1.add (b2);
    9. double a = c.doubleValue();
    10. System.out.println(a);
    11. }
    12. }

    运行结果如下:

          



  • 相关阅读:
    『51单片机』 DS1302时钟
    元宇宙虚拟空间的场景构造(二)
    解锁LLMs的“思考”能力:Chain-of-Thought(CoT) 技术推动复杂推理的新发展
    华为机试真题实战应用【赛题代码篇】-按照路径替换二叉树(附Java和C++代码实现)
    混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.1)
    Java 类和对象 详解+通俗易懂
    SSM的整合与使用
    JSP的特点与工作流程
    Boost研究:Boost Log
    repmgr管理pg高可用
  • 原文地址:https://blog.csdn.net/Tingfeng__/article/details/133812465