原创

Java之BigDecimal的学习

因为项目中需要精确计算,因此学习了以下bigdecimal这个类,以前感觉很难用,其实习惯了就行,他就是一个工具类。

以下摘自百度百科,仅仅是有用的。

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
BigDecimal一共有4个构造方法:
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。(不建议采用)
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
为什么不建议采用第二种构造方法?如下代码:

public static void main(String[] args) {
BigDecimal d1 = new BigDecimal(2);
BigDecimal d2 = new BigDecimal(2.3);
BigDecimal d3 = new BigDecimal("2.3");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
}
2
2.29999999999999982236431605997495353221893310546875
2.3

原因:JDK的描述:1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下:

public static void main(String[] args) {

    BigDecimal d4 = BigDecimal.valueOf(2.3);
    BigDecimal d5 = new BigDecimal(Double.toString(2.3));

    System.out.println(d4);
    System.out.println(d5);
}

2.3
2.3

public BigDecimal add(BigDecimal value); //加法

  public BigDecimal subtract(BigDecimal value); //减法
  public BigDecimal multiply(BigDecimal value); //乘法
  public BigDecimal divide(BigDecimal value); //除法
工具类

package com.util;

import java.math.BigDecimal;

/**

  • [说明/描述] BigDecimal工具类,解决String 转Double 损失精度的问题
  • @author
  • @date 2018-11-19 下午3:30:05
  • @company
  • @version 1.0
  • @copyright copyright (c) 2018
    */

public class Arith {

 //默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
//这个类不能实例化
private Arith(){
}

//加
public static double add(String v1,double v2){
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
//加
public static BigDecimal add(String v1,String v2){
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return b1.add(b2);
}
/**

  • //减
  • [描述信息]
  • @author
  • @date 2018-11-19 下午4:10:04
  • @param v1
  • @param v2
  • @return

    */
    public static BigDecimal sub(String v1,String v2){
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.subtract(b2);
    }

    /**

    • [描述信息] //乘
    • @author
    • @date 2018-11-19 下午4:09:50
    • @param v1
    • @param v2
    • @return

      */
      public static double mul(double v1,double v2){
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.multiply(b2).doubleValue();
      }

    /**

    • 除法运算
    • [描述信息]
    • @author
    • @date 2018-11-19 下午4:09:33
    • @param v1
    • @param v2
    • @param scale
    • @return

      */
      public static double div(String v1,double v2,int scale){
      if(scale<0){
       throw new IllegalArgumentException(
           "The scale must be a positive integer or zero");
      
      }
      BigDecimal b1 = new BigDecimal(v1);
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
      }

    public static BigDecimal div(String v1,String v2,int scale){
    if(scale<0){

       throw new IllegalArgumentException(
           "The scale must be a positive integer or zero");
    

    }
    BigDecimal b1 = new BigDecimal(v1);
    BigDecimal b2 = new BigDecimal(v2);
    return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP);
    }

    public static double round(double v,int scale){
    if(scale<0){

       throw new IllegalArgumentException(
           "The scale must be a positive integer or zero");
    

    }
    BigDecimal b = new BigDecimal(Double.toString(v));
    BigDecimal one = new BigDecimal("1");
    return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    public static double StringToDouble(String v){
    BigDecimal maxlng1 = new BigDecimal(v);

    return maxlng1.doubleValue();
    }
    public static void main(String[] args) {
    System.out.println(sub("0.10", "0.000"));
    }

}

Java之BigDecimal的学

正文到此结束(点击广告是对作者最大的支持)