content: package com.jingewenku.abrahamcaijin.commonutil;
  
  
  
  import java.math.BigDecimal;
  
  
  /**
   * 主要功能： 资金运算工具类
   * @Prject: CommonUtilLibrary
   * @Package: com.jingewenku.abrahamcaijin.commonutil
   * @author: AbrahamCaiJin
   * @date: 2017年05月03日 16:37
   * @Copyright: 个人版权所有
   * @Company:
   * @version: 1.0.0
   */
  public class AppBigDecimal {
  	
  	
  	
  	   private static final int DEF_DIV_SCALE = 10;  
  	  
  	    /** 
  	     * 提供精确的加法运算  
  	     * @param v1 被加数 
  	     * @param v2 加数 
  	     * @return 两个参数的和 
  	     */  
  	    public static double add(double v1, double v2) {  
  	        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  	        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  	        return b1.add(b2).doubleValue();  
  	    }
  
  		/**
  		 * 提供精确的加法运算
  		 *
  		 * @param v1 被加数
  		 * @param v2 加数
  		 * @return 两个参数的和
  		 */
  		public static BigDecimal add(String v1, String v2) {
  			BigDecimal b1 = new BigDecimal(v1);
  			BigDecimal b2 = new BigDecimal(v2);
  			return b1.add(b2);
  		}
  
          /**
           * 提供精确的加法运算
           *
           * @param v1    被加数
           * @param v2    加数
           * @param scale 保留scale 位小数
           * @return 两个参数的和
           */
          public static String add(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.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  
          /**
               * 提供精确的减法运算
               * @param v1 被减数
               * @param v2 减数
               * @return 两个参数的差
               */
              public static double substract(double v1, double v2) {
                  BigDecimal b1 = new BigDecimal(Double.toString(v1));
                  BigDecimal b2 = new BigDecimal(Double.toString(v2));
                  return b1.subtract(b2).doubleValue();
              }
  
  		/**
  		 * 提供精确的减法运算。
  		 *
  		 * @param v1 被减数
  		 * @param v2 减数
  		 * @return 两个参数的差
  		 */
  		public static BigDecimal substract(String v1, String v2) {
  			BigDecimal b1 = new BigDecimal(v1);
  			BigDecimal b2 = new BigDecimal(v2);
  			return b1.subtract(b2);
  		}
  
          /**
           * 提供精确的减法运算
           *
           * @param v1    被减数
           * @param v2    减数
           * @param scale 保留scale 位小数
           * @return 两个参数的差
           */
          public static String substract(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.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  
  		/**
  	     * 提供精确的乘法运算 
  	     * @param v1 被乘数 
  	     * @param v2 乘数 
  	     * @return 两个参数的积 
  	     */  
  	    public static double multiply(double v1, double v2) {  
  	        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  	        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  	        return b1.multiply(b2).doubleValue();  
  	    }
  
          /**
           * 提供精确的乘法运算
           *
           * @param v1    被乘数
           * @param v2    乘数
           * @param scale 保留scale 位小数
           * @return 两个参数的积
           */
          public static double multiply(double v1, double v2, int scale) {
              BigDecimal b1 = new BigDecimal(Double.toString(v1));
              BigDecimal b2 = new BigDecimal(Double.toString(v2));
              return round(b1.multiply(b2).doubleValue(), scale);
          }
  
          /**
           * 提供精确的乘法运算
           *
           * @param v1    被乘数
           * @param v2    乘数
           * @param scale 保留scale 位小数
           * @return 两个参数的积
           */
          public static String multiply(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.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  
  	    /** 
  	     * 提供（相对）精确的除法运算,当发生除不尽的情况时, 
  	     * 精确到小数点以后10位,以后的数字四舍五入. 
  	     * @param v1 被除数 
  	     * @param v2 除数 
  	     * @return 两个参数的商 
  	     */  
  	    public static double divide(double v1, double v2) {  
  	        return divide(v1, v2, DEF_DIV_SCALE);  
  	    }  
  
  
  	    /** 
  	     * 提供（相对）精确的除法运算. 
  	     * 当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入. 
  	     *  
  	     * @param v1 被除数 
  	     * @param v2 除数 
  	     * @param scale 表示需要精确到小数点以后几位 
  	     * @return 两个参数的商 
  	     */  
  	    public static double divide(double v1, double v2, int scale) {  
  	        if (scale < 0) {  
  	            throw new IllegalArgumentException("The scale must be a positive integer or zero");  
  	        }  
  	          
  	        BigDecimal b1 = new BigDecimal(Double.toString(v1));  
  	        BigDecimal b2 = new BigDecimal(Double.toString(v2));  
  	        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();  
  	    }
  
          /**
           * 提供（相对）精确的除法运算。当发生除不尽的情况时，由scale参数指
           * 定精度，以后的数字四舍五入
           *
           * @param v1    被除数
           * @param v2    除数
           * @param scale 表示需要精确到小数点以后几位
           * @return 两个参数的商
           */
          public static String divide(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(v1);
              return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  	  
  	    /** 
  	     * 提供精确的小数位四舍五入处理 
  	     * @param v 需要四舍五入的数字 
  	     * @param scale 小数点后保留几位 
  	     * @return 四舍五入后的结果 
  	     */  
  	    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();  
  	    }
  
          /**
           * 提供精确的小数位四舍五入处理
           *
           * @param v     需要四舍五入的数字
           * @param scale 小数点后保留几位
           * @return 四舍五入后的结果
           */
          public static String round(String v, int scale) {
              if (scale < 0) {
                  throw new IllegalArgumentException(
                      "The scale must be a positive integer or zero");
              }
              BigDecimal b = new BigDecimal(v);
              return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  
          /**
           * 取余数
           *
           * @param v1    被除数
           * @param v2    除数
           * @param scale 小数点后保留几位
           * @return 余数
           */
          public static String remainder(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.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
          }
  
          /**
           * 取余数  BigDecimal
           *
           * @param v1    被除数
           * @param v2    除数
           * @param scale 小数点后保留几位
           * @return 余数
           */
          public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {
              if (scale < 0) {
                  throw new IllegalArgumentException(
                      "The scale must be a positive integer or zero");
              }
              return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
          }
  
  
          /**
  	     * 金额分割，四舍五人金额
  	     * @param s
  	     * @return
  	     */
  	    public static String formatMoney(BigDecimal s){
  	        String retVal = "";
  	        String str = "";
  	        boolean is_positive_integer = false;
  	        if(null == s){
  	        	return "0.00";
  	        }
  
  	        if(0 == s.doubleValue()){
  	        	return "0.00";
  	        }
  	        //判断是否正整数
  	        if(s.toString().indexOf("-") != -1){
  	        	is_positive_integer = true;
  	        }else{
  	        	is_positive_integer = false;
  	        }
  	        //是负整数
  	        if(is_positive_integer){
  	        	//去掉 - 号
  	        	s = new BigDecimal(s.toString().substring(1, s.toString().length()));
  	        }
  	        str = s.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
  	        StringBuffer sb = new StringBuffer();
  		    String[] strs = str.split("\\.");
  		    int j = 1;
  		    for(int i = 0; i < strs[0].length(); i++){
  		          char a = strs[0].charAt(strs[0].length()-i-1);
  		          sb.append(a);
  	        	  if(j % 3 == 0 && i != strs[0].length()-1){
  	        		  sb.append(",");
  	        	  }
  		          j++;
  		    }
  		    String str1 = sb.toString();
  		    StringBuffer sb1 = new StringBuffer();
  		    for(int i = 0; i < str1.length(); i++){
  		          char a = str1.charAt(str1.length()-1-i);
  		          sb1.append(a);
  		    }
  		        sb1.append(".");
  		        sb1.append(strs[1]);
  		        retVal = sb1.toString();
  		        
  		   if(is_positive_integer){
  		        	retVal = "-" + retVal;
  		   }
  		   		return retVal;
  	    }
  	    
  	    /**
  	     * 四舍五人金额
  	     * @param s
  	     * @return
  	     */
  	    public static String formatMoney1(BigDecimal s){
  	        String retVal = "";
  	        String str = "";
  	        boolean is_positive_integer = false;
  	        if(null == s){
  	        	return "0.00";
  	        }
  
  	        if(0 == s.doubleValue()){
  	        	return "0.00";
  	        }
  	        //判断是否正整数
  	        if(s.toString().indexOf("-") != -1){
  	        	is_positive_integer = true;
  	        }else{
  	        	is_positive_integer = false;
  	        }
  	        //是负整数
  	        if(is_positive_integer){
  	        	//去掉 - 号
  	        	s = new BigDecimal(s.toString().substring(1, s.toString().length()));
  	        }
  	        str = s.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
  	        StringBuffer sb = new StringBuffer();
  		    String[] strs = str.split("\\.");
  		    int j = 1;
  		    for(int i = 0; i < strs[0].length(); i++){
  		          char a = strs[0].charAt(strs[0].length()-i-1);
  		          sb.append(a);
  	        	  if(j % 3 == 0 && i != strs[0].length()-1){
  	        		  sb.append("");
  	        	  }
  		          j++;
  		    }
  		    String str1 = sb.toString();
  		    StringBuffer sb1 = new StringBuffer();
  		    for(int i = 0; i < str1.length(); i++){
  		          char a = str1.charAt(str1.length()-1-i);
  		          sb1.append(a);
  		    }
  		        sb1.append(".");
  		        sb1.append(strs[1]);
  		        retVal = sb1.toString();
  		        
  		   if(is_positive_integer){
  		        	retVal = "-" + retVal;
  		   }
  		   		return retVal;
  	    }
  
  	    /**
           * 比较大小
  		 * @param amount   输入的数值 
  		 * @param compare   被比较的数字
  		 * @return  true 大于被比较的数 
  		 */
  		public static Boolean compareBigDecimal(String amount , double  compare){
  			
  			  BigDecimal lenth=new BigDecimal(amount);
  		    	if(lenth.compareTo(BigDecimal.valueOf(compare))==-1){
  		    		return false;
  		    	}
  				return true;
  		}
  
      /**
       * 获取自己想要的数据格式
       * @param s 需处理的数据
       * @param numOfIntPart 整数位数
       * @param numOfDecimalPart 小数位数
       * @return 处理过的数据
       */
      public static String adjustDouble(String s,int numOfIntPart,int numOfDecimalPart){
  
          //按小数点的位置分割成整数部分和小数部分
          String[] array = s.split("\\.");
          char[] tempA=new char[numOfIntPart];
          char[] tempB=new char[numOfDecimalPart];
          //整数部分满足精度要求(情况1)
          if(array[0].length()==numOfIntPart){
              //直接获取整数部分长度字符
              for(int i=0;i<array[0].length();i++){
                  tempA[i]=array[0].charAt(i);
              }
              //小数部分精度大于或等于指定的精度
              if(numOfDecimalPart<=array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      tempB[i]=array[1].charAt(i);
  
                  }
              }
              //小数部分精度小于指定的精度
              if(numOfDecimalPart>array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      if(i<array[1].length()){
                          tempB[i]=array[1].charAt(i);
                      }else{
                          tempB[i]='0';
                      }
  
  
                  }
              }
              if(numOfDecimalPart==0){
                  return String.valueOf(tempA)+String.valueOf(tempB);
              }
              return String.valueOf(tempA)+"."+String.valueOf(tempB);
          }
  
          //整数部分位数大于精度要求(情况2)
          if(array[0].length()>numOfIntPart){
              //先倒序获取指定位数的整数
              for(int i=array[0].length()-1,j=0;(i>=array[0].length()-numOfIntPart)&&(j<numOfIntPart);i--,j++){
                  tempA[j]=array[0].charAt(i);
                  System.out.println(tempA[j]);
              }
              char[] tempA1=new char[numOfIntPart];
              //调整顺序
              for(int j=0,k=tempA.length-1;j<numOfIntPart&&(k>=0);j++,k--){
                  tempA1[j]=tempA[k];
                  System.out.println("tempA1[j]"+tempA1[j]);
  
              }
              //小数部分精度大于或等于指定的精度
              if(numOfDecimalPart<=array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      tempB[i]=array[1].charAt(i);
  
                  }
  
              }
              //小数部分精度小于指定的精度
              if(numOfDecimalPart>array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      if(i<array[1].length()){
                          tempB[i]=array[1].charAt(i);
                      }else{
                          tempB[i]='0';
                      }
  
  
                  }
              }
  
              return String.valueOf(tempA1)+"."+String.valueOf(tempB);
          }
  
  
          //整数部分满足精度要求(情况3)
          if(array[0].length()==numOfIntPart){
              //直接获取整数部分长度字符
              for(int i=0;i<array[0].length();i++){
                  tempA[i]=array[0].charAt(i);
              }
              //小数部分精度小于指定的精度
              if(numOfDecimalPart>array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      if(i<array[1].length()){
                          tempB[i]=array[1].charAt(i);
                      }else{
                          tempB[i]='0';
                      }
  
  
                  }
              }
  
              //小数部分精度大于或等于指定的精度
              if(numOfDecimalPart<=array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      tempB[i]=array[1].charAt(i);
  
                  }
  
              }
              if(numOfDecimalPart==0){
                  return String.valueOf(tempA)+String.valueOf(tempB);
              }
              return String.valueOf(tempA)+"."+String.valueOf(tempB);
          }
  
          //整数部分大于精度要求(情况4)
          if(array[0].length()>numOfIntPart){
              //先倒序获取指定位数的整数
              for(int i=array[0].length()-1,j=0;(i>=array[0].length()-numOfIntPart+1)&&(j<numOfIntPart);i--,j++){
                  //System.out.println("<<<<"+(i-array[0].length()+1));
                  tempA[j]=array[0].charAt(i);
              }
              char[] tempA1=new char[numOfIntPart];
              //调整顺序
              for(int j=0,k=tempA.length-1;j<numOfIntPart&&(k>=0);j++){
                  tempA1[j]=tempA[k];
                  k--;
              }
  
              //小数部分精度小于指定的精度
              if(numOfDecimalPart>array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      if(i>=array[1].length()){
                          tempB[i]='0';
  
                      }else{
                          tempB[i]=array[1].charAt(i);
                      }
  
  
                  }
              }
              //小数部分精度大于或等于指定的精度
              if(numOfDecimalPart<=array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      tempB[i]=array[1].charAt(i);
  
                  }
  
              }
  
              if(numOfDecimalPart==0){
                  return String.valueOf(tempA1)+String.valueOf(tempB);
              }
              return String.valueOf(tempA1)+"."+String.valueOf(tempB);
          }
  
          //整数部分小于精度要求(情况5)
          if(array[0].length()<numOfIntPart){
              //先倒序获取指定位数的整数
              char[] tempA1=new char[numOfIntPart];
              for(int i=array[0].length()-1,j=0;(i>=numOfIntPart-array[0].length()-(numOfIntPart-array[0].length()))&&(j<numOfIntPart);i--,j++){
                  tempA1[j]=array[0].charAt(i);
                  System.out.println("<<<<<<tempA1[j]"+tempA1[j]);
              }
  
              //补0
              for(int i=array[0].length();i<array[0].length()+numOfIntPart-array[0].length();i++){
                  tempA1[i]='0';
  
                  System.out.println("<<<<<<"+tempA1[i]);
              }
  
              char[] tempA2=new char[numOfIntPart];
              //调整顺序
              for(int j=0,k=tempA1.length-1;j<numOfIntPart&&(k>=0);j++){
                  tempA2[j]=tempA1[k];
                  k--;
              }
              //小数部分精度小于指定的精度
              if(numOfDecimalPart>array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      if(i<array[1].length()){
                          tempB[i]=array[1].charAt(i);
                      }else{
                          tempB[i]='0';
                      }
                  }
              }
              //小数部分精度大于或等于指定的精度
              if(numOfDecimalPart<=array[1].length()){
                  for(int i=0;i<numOfDecimalPart;i++){
                      tempB[i]=array[1].charAt(i);
  
                  }
              }
              if(numOfDecimalPart==0){
                  return String.valueOf(tempA2)+String.valueOf(tempB);
              }
              return String.valueOf(tempA2)+"."+String.valueOf(tempB);
          }
  
          //情况(6)
          if((array[0].length()<numOfIntPart)&&(array[1].length()<numOfDecimalPart)){
              for(int i=0; i< numOfIntPart-array[0].length(); i++){
                  s = "0"+s ;
              }
  
              for(int i = 0 ; i < numOfDecimalPart -array[1].length() ; i++){
                  s = s+"0" ;
              }
              return s;
          }
  
          return null;
      }
  
  
      public static void main(String[] args) {
  	    	 System.out.println("金额0：         " + formatMoney1(new BigDecimal(0)));
  	    	 System.out.println("金额0.0 ：         " + formatMoney1(new BigDecimal(0.0)));
  	    	 System.out.println("金额0.00：         " + formatMoney1(new BigDecimal(0.00)));
  	    	 System.out.println("金额0.58：         " + formatMoney1(new BigDecimal(0.58)));
  	    	 System.out.println("金额5.58：         " + formatMoney1(new BigDecimal(5.58)));
  	    	 System.out.println("金额5.54：          " + formatMoney1(new BigDecimal(5.54)));
  	    	 System.out.println("金额512322.555555111：          " + formatMoney1(new BigDecimal(512322.555555111)));
  	    	 System.out.println("金额3423423425.54：     " + formatMoney1(new BigDecimal(3423423425.54)));
  	    	 System.out.println("金额3423423425.58：      " + formatMoney1(new BigDecimal(3423423425.58)));
  	    	 System.out.println("金额1000000.543453：     " + formatMoney1(new BigDecimal(1000000.543453)));
  	    	 System.out.println("金额9343788754.573453：     " + formatMoney1(new BigDecimal(-9343788754.573453)));
  	    	 System.out.println("金额9343788756.577：     " + formatMoney1(new BigDecimal(-9343788756.577)));
  	    	 System.out.println("金额-343788756.577：     " + formatMoney1(new BigDecimal(-343788756.577)));
  	    	 System.out.println("金额-34756.54：     " + formatMoney1(new BigDecimal(-34756.54)));
  	    	 System.out.println("金额-34756.556：     " + formatMoney1(new BigDecimal(-34756.556)));
  	    	 
  	    	 //DateUtils.rollDay(new Date(), -15);
  	         //直接使用浮点数进行计算，得到的结果是有问题的  
  	         //System.out.println(0.01 + 0.05);  
  	           
  	         //使用了BigDecimal类进行计算后，可以做到精确计算  
  	         //System.out.println(BigDecimalMoney.add(0.0000000000005, 0.00000001));  
  	    }  
  	     
  }
  