`

java之BigDecimal

阅读更多
一、背景知识:

由于 java 中 double 所表示的精度是有限的,而且对于小数的运算不够准确。
java 提供了 BigDecimal 类,专门用于数的准确计算。这一点可以满足金融行业的需求。


二、正式开始:

BigDecimal 可以操作任意精度位数的十进制数字。

1、BigDecimal 由两部分组成:[unscaled value, scale]

1. 不定规模的值(unscaled value):
     该值是一个任意精度的整数(arbitrary precision integer)。

2. 规模(scale):
     是一个32位的整数(integer)。 可以用以下任一种方法:

     ● 如果 规模(scale)的值是 0 或 正数: 规模(scale)的值代表 BigDecimal 小数点右侧数字的个数。
        例如: [19,2] 所表示的值是: 0.19

     ● 如果 规模(scale)的值是 负数: 不定规模的值(unscaled value)乘以 10 的规模(scale)值的幂次方,得到 BigDecimal 真实值的大小。
        例如: [19,-2] 所表示的值是: 19 * 10⁻² = 0.19

    
2、BigDecimal 提供的操作:
     算数(加减乘除),规模控制,近似值,大小比较,哈希值,格式转换。


3、查看 BigDecimal 所表示的值:
     toString():     将 BigDecimal 所代表的值以字符串形式显示。如果有需要,会使用科学计数法显示。
     toPlainString(): 将 BigDecimal 所代表的值以字符串形式显示。不用科学计数法显示。


4、对于求近似值:
     如果一个数的小数部分是无限的(例如 1/3),而又没有指定取舍模式(rounding mode)(四舍五入、取整、等),则会抛出异常。
     如果一个数是有限的,可以通过使用 MathContext 对象指定计算时使用的精度(precision)和取舍模式(rounding mode)。


5、对于取舍模式:
     BigDecimal 类内部使用8个整型常量提供了8种取舍模式(如: ROUND_HALF_UP 四舍五入),但这种方法已被弃用。
     请使用 RoundingMode 对象的常量属性。(如: RoundingMode.HALF_UP )


6、对于精度:
精度计算:
     从运算结果的最左侧第一个不为0的数算起,直至末尾。
     例如:
           0.000042  的精度是 2
           0.0000420 的精度是 3


精度的值(jdk 1.5 及之前的版本):
     使用精度值为 0 (如: MathContext.UNLIMITED )的 MathContext 对象时,算数操作的结果是精确的。
     这是因为算数操作没有使用这个 MathContext 对象。由于没有指定精度,在操作无限数时会抛出异常。例如:除法运算 1/3

     使用精度值非0的 MathContext 对象时,算数的运算规则与 ANSI X3.274-1996 和 ANSI X3.274-1996/AM 1-2000 相兼容。
     BigDecimal 类还包含了其它的取舍模式。如果这些规则与 ANSI 标准相冲突,BigDecimal 会使用自己制定的运算规则。


7、对于运算结果的表示:
     使用算数运算和精度运算,对于运算结果的表示,必须指定数值结果(numerical result)和规模(scale)。
     因为:同一个值,因规模(scale)的不同,结果的表示也不同。


8、通常用法:
     如果运算结果的位数(可能是无限小数)大于需要的位数时,使用取舍模式和精度来共同决定运算结果如何返回。
     首先:使用 MathContext 对象设置精度。
     其次:使用 取舍模式决定要丢弃的尾部位数如何影响返回的结果。

     当取舍模式运算结果有进位而影响了所指定的精度时,则进位会被保留。
     如:对 999.9 做四舍五入,指定精度为 3位。返回值是:1000,此时输出结果为: 1.00 × 10³


9、算数操作的默认规模(scale)

    加法操作(a+b):    max(a.scale(), b.scale())
    减法操作(a-b):    max(a.scale(), b.scale())
    乘法操作(a*b):    a.scale() + b.scale()
    除法操作(a/b):    a.scale() - b.scale()
   
    特别注意:
    除法操作请指定规模,而不能使用默认的规模。
    例如: 1/32 的结果是 0.03125


10、算数操作的规模(scale)
   
     - 在对运算结果做取舍操作之前,逻辑中间运算结果的 scale 被默认设置为取舍运算的 scale。
     - 如果运算结果是无限小数,则运算结果的scale是根据设定的精度做取舍运算后得到的 scale。
     - 如果运算结果是有限数,则运算结果的scale会取值为最接近默认设置的 scale 。
       除法运算会使运算结果的 scale 变小,例如:
       scale 变小的情况: 19/100 = 0.19   // integer=19, scale=2
       scale 不变的情况: 21/110 = 0.190  // integer=190, scale=3
  
       注意:对于加法、减法、乘法,运算结果的 scale 的减小等于运算结果舍弃的位数。
             如果取舍运算有进位的情况,运算结果的附加数字将被丢弃。
        

11、两种会影响规模(scale)的操作:
    1. setScale()/round() 操作。返回 BigDecimal 类型。
    2. 小数点移动操作( movePointLeft() / movePointRight() )。返回 BigDecimal 类型。
   
12、注意:
    在使用具有大小排序功能的类时(如: SortedMap, SortedSet ),
    BigDecimal 不能按照其所代表的值的真实大小排序。因为 BigDecimal 的 equals() 方法与 BigDecimal 值的大小不符。
   
   
              


13、讨论:

(一)精度(precision)与规模(scale)

    BigDecimal b1 =  
    new BigDecimal("35.3456").round(new MathContext(4, RoundingMode.HALF_UP)); 
    System.out.println(b1.toString()); //result = 35.35

    BigDecimal b2 =  
    new BigDecimal("35.3456").setScale(4, RoundingMode.HALF_UP); 
    System.out.println(b2.toString()); // result = 35.3456



(二)有进位的情况

    BigDecimal b3 =    
        new BigDecimal("999.9").round(new MathContext(3, RoundingMode.HALF_UP));       
    System.out.println(b3.toString());       // 1.00E+3
        
    System.out.println(b3.toPlainString());  // 1000
    System.out.println(b3.precision());      // 3
       
        
    BigDecimal b4 = new BigDecimal("2000");                
    System.out.println(b4.toString());       // 2000


   
(三)与 double 比较

    double a = 0.02;
    double b = 0.03;
    double c = b - a;
    System.out.println(c);                       // 0.009999999999999998

    BigDecimal _a = new BigDecimal("0.02");
    BigDecimal _b = new BigDecimal("0.03");
    BigDecimal _c = _b.subtract(_a);
    System.out.println(_c);                      // 0.01

   
   
   
  







-
引用:
https://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html



-
转载请注明
原文出处: http://lixh1986.iteye.com/blog/2323077
-





-

分享到:
评论

相关推荐

    java中BigDecimal的操作方法

    在Java编程语言中,BigDecimal是用于处理高精度和可配置精度的十进制数的类。在进行商业计算时,由于浮点数(double和float)存在精度问题,不能保证准确的结果,因此通常推荐使用BigDecimal来确保计算的精确性。本文...

    java BigDecimal操作

    总的来说,理解和熟练运用BigDecimal是每个Java开发者必备的技能之一,特别是在处理货币计算、财务计算等场景时,能够避免因为浮点数精度问题导致的错误。在使用BigDecimal时,一定要注意其性能开销,因为它比基本的...

    Java SE程序 BigDecimal类

    Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE程序 BigDecimal类Java SE...

    Java中BigDecimal的加减乘除、比较大小与使用注意事项

    在Java编程中,当涉及到需要精确数值计算的场景时,我们通常会使用`BigDecimal`类。这是因为`float`和`double`类型虽然适用于科学计算和工程计算,但它们基于二进制浮点运算,不能保证完全精确的结果。而`BigDecimal...

    关于java中BigDecimal的简介(csdn)————程序.pdf

    Java中的`BigDecimal`类是用于表示和操作高精度浮点数的重要工具,尤其适用于需要进行精确计算的场景,如财务和货币计算。由于基本数据类型`double`和`float`在进行大数值或高精度计算时可能会导致精度丢失,因此`...

    Java编程BigDecimal用法实例分享

    Java编程BigDecimal用法实例分享 Java中的BigDecimal类是Java标准库中的一部分,用于处理高精度的数字计算,特别是在商业计算中对数字精度要求较高的场景中。BigDecimal类提供了对大数字的操作,可以精确地计算货币...

    Java中BigDecimal类的使用详解

    Java中BigDecimal类的使用详解 Java中BigDecimal类是Java.math包中提供的一个API类,用于对超过16位有效位的数进行精确的运算。由于浮点数的精度问题,Java中浮点数的计算会失去一定的精确度。因此,使用BigDecimal...

    java-BigInteger-BigDecimal类源码

    在Java编程语言中,`BigInteger`和`BigDecimal`是两个重要的类,它们分别用于处理大整数和高精度浮点数。这两个类位于`java.math`包下,为开发者提供了超越基本数据类型(如int、long和double)的计算能力。在深入...

    Java中BigDecimal的基本运算(详解)

    Java中BigDecimal的基本运算详解 Java中的BigDecimal是一种高精度的数据类型,它可以用来表示非常大的整数和小数,提供了丰富的数学运算功能。下面我们将对Java中BigDecimal的基本运算进行详细的介绍。 构造方法 ...

    Java对BigDecimal常用方法的归类 -计算机等级考试-考试吧

    JAVA基础:java.math.BigDecimal的使用方法. JAVA基础:java.math.BigDecimal的使用方法.

    Java中BigDecimal类的简单用法

    因此,理解并熟练运用BigDecimal类是每个Java程序员必备的技能之一。在编写涉及精确数值计算的代码时,应优先考虑使用BigDecimal,以避免因浮点数不精确而导致的问题。同时,需要注意的是,BigDecimal的操作相对于...

    Java对BigDecimal常用方法的归类(加减乘除).doc

    Java 中 BigDecimal 的常用方法归类(加减乘除) Java 中的 BigDecimal 类提供了对浮点数的精确运算,包括加减乘除和四舍五入等操作。在 Java 中,简单类型不能够精确地对浮点数进行运算,因此需要使用 BigDecimal ...

    Java使用BigDecimal进行运算封装的实际案例

    "Java使用BigDecimal进行运算封装的实际案例" 今天,我们将讨论Java中使用BigDecimal进行运算封装的实际案例。BigDecimal是Java中一个用于处理精确数字计算的类,它提供了多种数学运算方法,如加法、减法、乘法、除...

    java.math.BigDecimal 操作类

    java.math.BigDecimal 操作类,包含加减乘除、String型加减乘除精度格式化转换计算等

    Java Bigdecimal使用原理详解

    Java Bigdecimal使用原理详解 Java Bigdecimal是Java语言中用于精确计算的类,它可以完善float和double类无法进行精确计算的缺憾。BigDecimal类位于java.math类包下,提供了多种构造函数和方法来实现精确计算。 ...

    BigDecimal开n次方根

    复杂的BigDecimal计算,需要开方的式子,可输入结果精确位数

    Java BigDecimal类用法详解

    Java中的`BigDecimal`类是用来表示任意精度的十进制数,尤其适合于需要精确计算的商业和财务场景。它的核心概念包括非标度值(unscaled value)和标度(scale),非标度值是一个任意精度的整数,标度则是小数点后的...

    BigDecimal类

    BigDecimal 类是 Java 中的一种数值类型,主要用于处理超过 16 位有效数字的数值运算。该类提供了多种构造器和方法,用于创建和操作 BigDecimal 对象。 构造器 BigDecimal 类提供了四种构造器,用于创建不同的 ...

    BigDecimal工具类.docx

    BigDecimal工具类是Java中用于高精确处理常用数学运算的工具类。该工具类提供了多种精确的数学运算方法,包括加法、减法、乘法和除法等。 在BigDecimal工具类中,我们可以看到多个重载的方法,例如add方法和sub方法...

    浅谈java中BigDecimal类的简单用法

    相比之下,使用 `BigDecimal(String)` 构造函数创建 `new BigDecimal("0.1")` 将得到预期的0.1。当从 `double` 转换为 `BigDecimal` 时,建议使用 `BigDecimal.valueOf(double)` 方法,它会提供准确的转换。 ### ...

Global site tag (gtag.js) - Google Analytics