• BigDecimal 小数 浮点数 精度 财务计算


    简介

    float和double类型的使用局限:
    • 精度浮点型变量float可以处理6~7位有效数双精度浮点型变量double可以处理15~16位有效数,在实际应用中,如果需要对更大或者更小的数进行运算和处理,这时候float和double就如能为力了
    • 借用《Effactive Java》这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算,他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦。

    BigDecimal
    public class BigDecimal extends Number implements Comparable<BigDecimal>
    BigDecimal用来对超过16位有效位的数进行精确的运算。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
    BigDecimal 由【任意精度的整数非标度值】【32 位的整数标度 (scale)】组成。如果为零或正数,则标度是小数点后的位数;如果为负数,则将该数的非标度值乘以 10 的负scale 次幂。因此,BigDecimal表示的数值是【unscaledValue * 10^-scale】。

    JDK中对BigDecimal的定义为:不可变的、任意精度的有符号十进制数。
    BigDecimal 类提供以下操作:算术、标度操作、舍入、比较、哈希算法和格式转换。toString() 方法提供 BigDecimal 的规范表示形式。

    注意,BigDecimal对象是不可变的(immutable)的(像String、BigInteger一样),我们在调用其加减乘除等方法后,其实最终都返回的是一个新的BigDecimal对象,所以在做每一步运算时一定要保存操作后的值。
    BigDecimal bd = BigDecimal.valueOf(0.4);
    BigDecimal bd2 = BigDecimal.valueOf(0.6);
    bd.add(bd2);//虽然做了加法操作,但是bd并没有保存加操作后的值
    bd2 = bd.add(bd2);//bd2指向了一个新的BigDecimal对象的引用
    System.out.println(bd.doubleValue() + "  " + bd2.doubleValue());//0.4  1.0
    System.out.println(BigDecimal.valueOf(0.4).add(BigDecimal.valueOf(0.6)));//1.0。计算时一般都会链式调用

    MathContext 类

    public final class MathContext extends Object implements Serializable
    该对象是封装上下文设置的不可变对象,它描述数字运算符的某些规则,例如由 BigDecimal 类实现的规则。
    基本独立设置为:
    • precision:某个操作使用的数字个数;结果舍入到此精度
    • roundingMode:一个 RoundingMode 对象,该对象指定舍入使用的算法。

    构造方法
    • MathContext(int setPrecision)  构造一个新的 MathContext,它具有指定的精度和 HALF_UP 舍入模式。 参数setPrecision为非负 int 精度设置。
    • MathContext(int setPrecision, RoundingMode setRoundingMode)  构造一个新的 MathContext,它具有指定的精度和舍入模式。
    • MathContext(String val)  根据字符串构造一个新的 MathContext。该字符串的格式必须与 toString() 方法生成的字符串的格式相同。

    静态字段
    • static MathContext  DECIMAL128:一个 MathContext 对象,其精度设置与 IEEE 754R Decimal128 格式(即 34 个数字)匹配,舍入模式为 HALF_EVEN,这是 IEEE 754R 的默认舍入模式。
    • static MathContext  DECIMAL32 : 一个 MathContext 对象,其精度设置与 IEEE 754R Decimal32 格式(即 7 个数字)匹配,舍入模式为 HALF_EVEN,这是 IEEE 754R 的默认舍入模式。
    • static MathContext  DECIMAL64 : 一个 MathContext 对象,其精度设置与 IEEE 754R Decimal64 格式(即 16 个数字)匹配,舍入模式为 HALF_EVEN,这是 IEEE 754R 的默认舍入模式。
    • static MathContext  UNLIMITED : 其设置具有无限精度算法所需值的 MathContext 对象。该设置的值为: precision=0,roundingMode=HALF_UP
    PS:默认的HALF_EVEN模式不是"四舍五入"的模式,我们最好改为HALF_UP模式。

    公共方法
    • int  getPrecision()  返回 precision 设置。此值始终为非负数。
    • RoundingMode  getRoundingMode()  返回 roundingMode 设置。它将是8种RoundingMode之一。
    • boolean  equals(Object x)  将此 MathContext 与指定的 Object 进行相等性比较。
    • int  hashCode()  返回此 MathContext 的哈希码。
    • String  toString()  返回此 MathContext 的字符串表示形式。

    构造方法

    通过BigInteger构造BD

    • BigDecimal(BigInteger val)  将 BigInteger 转换为 BigDecimal。
    • BigDecimal(BigInteger unscaledVal, int scale)  将 BigInteger 非标度值和 int 标度转换为 BigDecimal。
    【带MathContext参数--根据上下文设置进行舍入
    • BigDecimal(BigInteger val, MathContext mc) 
    • BigDecimal(BigInteger unscaledVal, int scale, MathContext mc)

    通过char[]构造BD

    • BigDecimal(char[] in)  将 BigDecimal 的字符数组表示形式转换为 BigDecimal,接受与 BigDecimal(String) 构造方法相同的字符序列
    • BigDecimal(char[] in, int offset, int len)  将 BigDecimal 的字符数组表示形式转换为 BigDecimal,接受与 BigDecimal(String) 构造方法相同的字符序列,同时允许指定子数组
    【带MathContext参数--根据上下文设置进行舍入】
    • BigDecimal(char[] in, MathContext mc)
    • BigDecimal(char[] in, int offset, int len, MathContext mc)

    通过基本数据类型构造BD

    • BigDecimal(double val)  将 double 转换为 BigDecimal,后者是 double 的二进制浮点值准确的十进制表示形式。
    • BigDecimal(int val)  将 int 转换为 BigDecimal。
    • BigDecimal(long val)  将 long 转换为 BigDecimal。
    • BigDecimal(String val)  将 BigDecimal 的字符串表示形式转换为 BigDecimal。
    public BigDecimal(String val) {
        this(val.toCharArray(), 0, val.length());
    }
    【带MathContext参数--根据上下文设置进行舍入
    • BigDecimal(double val, MathContext mc)
    • BigDecimal(int val, MathContext mc)
    • BigDecimal(long val, MathContext mc)
    • BigDecimal(String val, MathContext mc)

    构造方法使用推荐

    1、不推荐使用含有double的构造方法
    参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入new BigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1,即 1*10^-1),但是它实际上等于***。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。
    String string=new BigDecimal(0.1).toEngineeringString();
    System.out.println(string + "  " + string.length());//0.1000000000000000055511151231257827021181583404541015625  57
    System.out.println(new BigDecimal(0.1).doubleValue() == 0.1);//true
    
    System.out.println(new BigDecimal(1.22) + "  " + new BigDecimal("1.22"));//1.2199999999999999733546474089962430298328399658203125  1.22
    System.out.println(new BigDecimal(1.22).doubleValue() == new BigDecimal("1.22").doubleValue());//true,并且都 == 1.22

    2、当 double 必须用作 BigDecimal 的源时,可使用下面两种方式之一:
    • 先使用 Double.toString 方法将 double 转换为 String,然后使用含有 String 的构造方法。
      含有 String 的构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用含有 String 的构造方法
    System.out.println(new BigDecimal("0.1") + "  " + new BigDecimal("0.1").toEngineeringString());//0.1  0.1
    • 也直接使用BigDecimal类中静态的valueOf方法,这通常是将 double 和 float 转换为一个 BigDecimal 的最好方式(第一种方式从本质上将也是采用的这种方式)
    public static BigDecimal valueOf(double val) {
        return new BigDecimal(Double.toString(val));//第一种方式从本质上将也是采用的这种方式
    }

    静态字段

    三个实例
    • static BigDecimal  ONE  值为 1,标度为 0。
    • static BigDecimal  TEN  值为 10,标度为 0。
    • static BigDecimal  ZERO  值为 0,标度为 0。  

    以下模式和RoundingMode中定义的模式是完全一致的,且JDK中建议使用RoundingMode中定义的模式。具体详见另一篇笔记。
    1. static int  ROUND_CEILING(天花板; 最高限度)  接近正无穷大的舍入模式。
    2. static int  ROUND_DOWN  接近零的舍入模式。
    3. static int  ROUND_FLOOR  接近负无穷大的舍入模式。
    4. static int  ROUND_UP  舍入远离零的舍入模式。
    5. static int  ROUND_UNNECESSARY  断言请求的操作具有精确的结果,因此不需要舍入。
    6. static int  ROUND_HALF_DOWN  向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
    7. static int  ROUND_HALF_EVEN  向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
    8. static int  ROUND_HALF_UP  向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。

    公共方法

    静态方法:将基本类型转换为BD

    • static BigDecimal  valueOf(double val)  返回值和 new BigDecimal(Double.toString(val)) 完全一致。
    • static BigDecimal  valueOf(long val)  将 long 值转换为具有零标度的 BigDecimal。
    • static BigDecimal  valueOf(long unscaledVal, int scale)  将 long 非标度值和 int 标度转换为 BigDecimal。

    获取标度、精度、正负号

    【获取标度、精度、正负号】
    • int  precision()  返回此 BigDecimal 的精度(精度是非标度值的数字【个数】)。零值的精度是 1。
    • int  scale()  返回此 BigDecimal 的标度。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以 10 的负 scale 次幂。例如, -3 标度是指非标度值乘以 1000。
    • int  signum()  返回此 BigDecimal 的正负号函数。当此 BigDecimal 的值为负、零或正时,返回 -1、0 或 1。
    System.out.println(BigDecimal.valueOf(54).precision() + "  " + BigDecimal.valueOf(54).scale());//2  0    54=54*10^0
    System.out.println(BigDecimal.valueOf(5).precision() + "  " + BigDecimal.valueOf(5).scale());//1  0    5=5*10^0
    System.out.println(BigDecimal.valueOf(5.4).precision() + "  " + BigDecimal.valueOf(5.4).scale());//2  1    5.4=54*10^-1
    System.out.println(BigDecimal.valueOf(0.054).precision() + "  " + BigDecimal.valueOf(0.054).scale());//2  3    0.054=54*10^-3
    【设置标度】
    • BigDecimal  setScale(int newScale)  返回一个 BigDecimal,其标度为指定值,其值在数值上等于此 BigDecimal 的值。如果这不可能,则抛出 ArithmeticException。
    • BigDecimal  setScale(int newScale, int roundingMode)  返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,以维护其总值。相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。
    • BigDecimal  setScale(int newScale, RoundingMode roundingMode)  返回 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,以维护其总值。
    BigDecimal bd = BigDecimal.valueOf(0.054);
    System.out.println(bd.precision() + "  " + bd.scale() + "  " + bd.signum());//2  3  1    0.054=54*10^-3
    BigDecimal bd2 = bd.setScale(4);
    System.out.println(bd.precision() + "  " + bd.scale() + "  " + bd.signum());//2  3  1,还是那句话:BigDecimal是不可变的!
    System.out.println(bd2.precision() + "  " + bd2.scale() + "  " + bd2.signum());//3  4  1    0.054=540*10^-4

    加减乘除幂

    1. BigDecimal  add(BigDecimal augend)  返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。
    2. BigDecimal  subtract(BigDecimal subtrahend)  返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。
    3. BigDecimal  multiply(BigDecimal multiplicand)  返回一个 BigDecimal,其值为 (this * multiplicand),其标度为 (this.scale() + multiplicand.scale())。
    4. BigDecimal  divide(BigDecimal divisor)  返回一个 BigDecimal,其值为 (this / divisor),其首选标度为 (this.scale() - divisor.scale());如果无法表示准确的商值(因为它有无穷的十进制扩展),则抛出 ArithmeticException。
    5. BigDecimal  pow(int n)  返回其值为 (this^n) 的 BigDecimal,准确计算该幂,使其具有无限精度。参数 n 必须在 0 到 999999999(包括)之间。ZERO.pow(0) 返回 ONE。 注意,未来版本可能会扩展此方法允许的指数范围。
    6. BigDecimal  scaleByPowerOfTen(int n)  返回其数值等于 (this * 10^n) 的 BigDecimal。该结果的标度为 (this.scale() - n)。
    【带MathContext参数--根据上下文设置进行舍入
    1. BigDecimal  add(BigDecimal augend, MathContext mc)
    2. BigDecimal  subtract(BigDecimal subtrahend, MathContext mc)
    3. BigDecimal  multiply(BigDecimal multiplicand, MathContext mc)
    4. BigDecimal  divide(BigDecimal divisor, MathContext mc)  返回其值为 (this / divisor) 的 BigDecimal(根据上下文设置进行舍入)。
    5. BigDecimal  pow(int n, MathContext mc)  返回其值为 (thisn) 的 BigDecimal。
    //测试加法 add
    double addValue = BigDecimal.valueOf(0.05).add(BigDecimal.valueOf(0.01)).doubleValue();
    System.out.println("0.05+0.01=" + (0.05 + 0.01) + "  " + addValue);//0.05+0.01=0.060000000000000005  0.06
    //测试减法 subtract
    double subtractValue = BigDecimal.valueOf(1.0).subtract(BigDecimal.valueOf(0.42)).doubleValue();
    System.out.println("1.0-0.42=" + (1.0 - 0.42) + "  " + subtractValue);//1.0-0.42=0.5800000000000001  0.58
    //测试乘法 multiply
    double multiplyValue = BigDecimal.valueOf(4.015).multiply(BigDecimal.valueOf(100)).doubleValue();
    System.out.println("4.015*100=" + (4.015 * 100) + "  " + multiplyValue);//4.015*100=401.49999999999994  401.5
    //测试除法 divide
    double divideValue = BigDecimal.valueOf(123.3).divide(BigDecimal.valueOf(100), 10, BigDecimal.ROUND_HALF_UP).doubleValue();
    System.out.println("123.3/100=" + (123.3 / 100) + "  " + divideValue);//123.3/100=1.2329999999999999  1.233
    //测试幂运算 pow、scaleByPowerOfTen
    System.out.println(Math.pow(1.1, 2) + "  " + BigDecimal.valueOf(1.1).pow(2).doubleValue());//1.2100000000000002  1.21
    System.out.println(BigDecimal.ONE.scaleByPowerOfTen(1024));//1E+1024
    【除法扩展_为除法指定舍入模式】
    • BigDecimal  divide(BigDecimal divisor, int roundingMode)  返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()。如果必须执行舍入,以生成具有给定标度的结果,则应用指定的舍入模式。相对于此遗留方法,应优先使用新的 divide(BigDecimal, RoundingMode) 方法。
    • BigDecimal  divide(BigDecimal divisor, RoundingMode roundingMode)  返回一个 BigDecimal,其值为 (this / divisor),其标度为 this.scale()如果必须执行舍入,以生成具有给定标度的结果,则应用指定的舍入模式。
    除法扩展_除法指定标度和舍入模式
    • BigDecimal  divide(BigDecimal divisor, int scale, int roundingMode)  返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。如果必须执行舍入,以生成具有指定标度的结果,则应用指定的舍入模式。相对于此遗留方法,应优先使用新的 divide(BigDecimal, int, RoundingMode) 方法。
    • BigDecimal  divide(BigDecimal divisor, int scale, RoundingMode roundingMode)  返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度。如果必须执行舍入,以生成具有指定标度的结果,则应用指定的舍入模式。

    取余和取整

    • BigDecimal  divideToIntegralValue(BigDecimal divisor)  返回 BigDecimal,其值为向下舍入所得商值(this / divisor)的整数部分。该结果的首选标度为(this.scale() - divisor.scale())。
    • BigDecimal  remainder(BigDecimal divisor)  返回其值为 (this % divisor) 的 BigDecimal。余数由 this.subtract( this.divideToIntegralValue(divisor) .multiply(divisor) ) 给出。注意,这不是模操作(结果可以为负)。
    • BigDecimal[]  divideAndRemainder(BigDecimal divisor)  返回由两个元素组成的 BigDecimal 数组,该数组包含 divideToIntegralValue 的结果,后跟对两个操作数计算所得到的 remainder。注意,如果同时需要整数商和余数,则此方法比分别使用 divideToIntegralValue 和 remainder 方法更快速,因为相除仅需执行一次。
    【带MathContext参数
    • BigDecimal  remainder(BigDecimal divisor, MathContext mc)
    • BigDecimal  divideToIntegralValue(BigDecimal divisor, MathContext mc)
    • BigDecimal[]  divideAndRemainder(BigDecimal divisor, MathContext mc)
    BigDecimal bd1 = BigDecimal.valueOf(5);
    BigDecimal bd2 = BigDecimal.valueOf(2);
    
    BigDecimal bd_div = bd1.divide(bd2);//商
    BigDecimal bd_dti = bd1.divideToIntegralValue(bd2);//向下舍入所得商值(this / divisor)的整数部分
    BigDecimal bd_tem = bd1.subtract(bd1.divideToIntegralValue(bd2).multiply(bd2));//remainder计算的过程
    BigDecimal bd_rem = bd1.remainder(bd2);//返回其值为 (this % divisor) 的 BigDecimal。注意,这不是模操作(结果可以为负)
    System.out.println(bd_div + "  " + bd_dti + "  " + bd_tem + "  " + bd_rem + "  " + bd_tem.equals(bd_rem));//2.5  2  1  1  true
    
    BigDecimal[] array = bd1.divideAndRemainder(bd2);
    System.out.println(Arrays.toString(array) + "  " + array[0].equals(bd_dti) + "  " + array[1].equals(bd_rem));//[2, 1]  true  true

    绝对值、正负值

    • BigDecimal  abs()  返回 BigDecimal,其值为此 BigDecimal 的绝对值,其标度为 this.scale()。
    • BigDecimal  negate()  返回 BigDecimal,其值为 (-this),其标度为 this.scale()。
    • BigDecimal  plus()  返回 BigDecimal,其值为 (+this),其标度为 this.scale()。此方法仅返回此 BigDecimal,该方法与一元减方法 negate() 对称
    【带MathContext参数
    • BigDecimal  abs(MathContext mc)  返回其值为此 BigDecimal 绝对值的 BigDecimal(根据上下文设置进行舍入)。
    • BigDecimal  negate(MathContext mc)  返回其值为 (-this) 的 BigDecimal(根据上下文设置进行舍入)。
    • BigDecimal  plus(MathContext mc)  返回其值为 (+this) 的 BigDecimal(根据上下文设置进行舍入)。此方法的效果与 round(MathContext) 方法的效果相同。

    其他返回BigDecimal的方法

    【最大最小值】
    • BigDecimal  max(BigDecimal val)  返回此 BigDecimal 和 val 的最大值。根据 compareTo 方法的定义,如果它们相等,则返回 this。
    • BigDecimal  min(BigDecimal val)  返回此 BigDecimal 和 val 的最小值。根据 compareTo 方法的定义,如果它们相等,则返回 this。
    【移动小数点】
    • BigDecimal  movePointLeft(int n)  返回一个 BigDecimal,它等效于将该值的小数点向左移动 n 位。如果 n 为非负数,则调用仅将 n 添加到该标度。如果 n 为负数,则该调用等效于 movePointRight(-n)。此调用返回的 BigDecimal 的值为 (this * 10^-n),标度为 max(this.scale()+n, 0)。
    • BigDecimal  movePointRight(int n)  返回一个 BigDecimal,它等效于将该值的小数点向右移动 n 位。如果 n 为非负数,则该调用仅从该标度减去 n。如果 n 为负,则该调用等效于 movePointLeft(-n)。此调用返回的 BigDecimal 的值为 (this * 10^n),标度为 max(this.scale()-n, 0)。
    【其他方法】
    • BigDecimal  stripTrailingZeros()  返回数值上等于此小数,但从该表示形式移除所有尾部零的 BigDecimal。
    • BigDecimal  ulp()  返回此 BigDecimal 的 ulp(最后一位的单位)的大小。
    • BigDecimal  round(MathContext mc)  返回根据 MathContext 设置进行舍入后的 BigDecimal。如果精度设置为 0,则不进行任何舍入操作。此方法的效果与 plus(MathContext) 方法的效果相同。

    转换为基本数据类型

    【基本收缩转换】
    1. int  intValue()  将此 BigDecimal 转换为 int。此转换类似于 Java Language Specification 中定义的从 double 到 short 的 基本收缩转换:将丢弃此 BigDecimal 的所有小数部分,并且如果生成的 " BigInteger" 太大而不适合用 int 表示,则仅返回 32 位低位字节。注意,此转换会丢失关于此 BigDecimal 值的总大小和精度的信息,并返回带有相反符号的结果。
    2. long  longValue()  将此 BigDecimal 转换为 long。此转换类似于 Java Language Specification 中定义的从 double 到 short 的 基本收缩转换:将丢弃此 BigDecimal 的小数部分,并且如果生成的 " BigInteger" 太大而不适合用 long 表示,则仅返回 64 位低位字节。注意,此转换会丢失关于此 BigDecimal 值的总大小和精度的信息,并返回带有相反符号的结果。
    3. float  floatValue()  将此 BigDecimal 转换为 float。此转换类似于 Java Language Specification 中定义的从 double 到 float 的 基本收缩转换:如此 BigDecimal 的值太大而不能表示为 float,则将其适当地转换为 Float.NEGATIVE_INFINITY 或 Float.POSITIVE_INFINITY。注意,即使在返回值为有限值的情况下,此转换也可能丢失关于 BigDecimal 值精度的信息。
    4. double  doubleValue()  将此 BigDecimal 转换为 double。此转换类似于 Java Language Specification 中定义的从 double 到 float 的 基本收缩转换:如果此 BigDecimal 的数量太大而不能表示为 double,则将其适当地转换为 Double.NEGATIVE_INFINITY 或 Double.POSITIVE_INFINITY。注意,即使在返回值为有限值的情况下,此转换也可能丢失关于 BigDecimal 值精度的信息。
    【转换为基本数据类型】
    1. byte  byteValueExact()  将此 BigDecimal 转换为 byte,以检查丢失的信息。如果此 BigDecimal 具有非零小数部分,或者超出 byte 结果的可能范围,则抛出 ArithmeticException。
    2. short  shortValueExact()  将此 BigDecimal 转换为 short,以检查丢失的信息。如果此 BigDecimal 具有非零小数部分,或者超出 short 结果的可能范围,则抛出 ArithmeticException。
    3. int  intValueExact()  将此 BigDecimal 转换为 int,以检查丢失的信息。如果此 BigDecimal 具有非零小数部分,或者超出 int 结果的可能范围,则抛出 ArithmeticException。
    4. long  longValueExact()  将此 BigDecimal 转换为 long,以检查丢失的信息。如果此 BigDecimal 具有非零小数部分,或者超出 long 结果的可能范围,则抛出 ArithmeticException。
    BigDecimal bd = BigDecimal.ONE.scaleByPowerOfTen(18);
    System.out.println(Long.MAX_VALUE + "  " + (Long.MAX_VALUE + "").length());//9223372036854775807  19
    System.out.println(bd.longValue() + "  " + bd.longValueExact() + "  " + (bd.longValue() + "").length());//1000000000000000000  1000000000000000000  19
    BigDecimal bd2 = BigDecimal.ONE.scaleByPowerOfTen(19);
    System.out.println(bd2 + "  " + bd2.longValue()+ "  " + bd2.doubleValue());//1E+19  -8446744073709551616  1.0E19
    try {
    	System.out.println(bd2.longValueExact());
    } catch (Exception e) {
    	e.printStackTrace();
    	System.out.println("如果此 BigDecimal 具有非零小数部分,或者超出 long 结果的可能范围,则抛出 ArithmeticException");
    }

    字符串表示形式

    • String  toString()  返回此 BigDecimal 的字符串表示形式,如果需要指数,则使用【科学记数法】
    • String  toEngineeringString()  返回此 BigDecimal 的字符串表示形式,需要指数时,则使用【工程计数法】
      • 返回如 toString() 方法中所描述的表示 BigDecimal 的字符串,不包括使用指数记数法的情况,将十的幂调整为三的倍数(工程记数法),这样,非零值的整数部分的范围是 1 到 999。如果对零值使用指数记数法,则使用小数点和小数的一(或二)个零数字,以便保留零值的标度。
    • String  toPlainString()  返回【不带指数字段】的此 BigDecimal 的字符串表示形式。

    转换为BigInteger

    • BigInteger  toBigInteger()  将此 BigDecimal 转换为 BigInteger。
    • BigInteger  toBigIntegerExact()  将此 BigDecimal 转换为 BigInteger,以检查丢失的信息。
    • BigInteger  unscaledValue()  返回其值为此 BigDecimal 的非标度值 的 BigInteger。计算 (this * 10^this.scale())。

    重载自Object的方法

    • int  compareTo(BigDecimal val)  将此 BigDecimal 与指定的 BigDecimal 比较。
    • int  hashCode()  返回此 BigDecimal 的哈希码。
    • boolean  equals(Object x)  比较此 BigDecimal 与指定的 Object 的相等性。
    2017-8-26




  • 相关阅读:
    Linux的概念与体系
    Python快速教程
    Qt控件精讲一:按钮
    xml2-config not found
    Ubuntu 12.04更新源
    Adaboost的几个人脸检测网站
    关于matlab矩阵卷积conv2和傅里叶变换求卷积ifft2的关系
    char数组和String互转
    STL中vector的赋值,遍历,查找,删除,自定义排序——sort,push_back,find,erase
    《离散数学》-图论6.7
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/7435475.html
Copyright © 2020-2023  润新知