JAVA 精度工具类

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.impl.io.SocketOutputBuffer;

public class ArithUtil {

	// 默认除法运算精度
	private static final int DEF_DIV_SCALE = 10;

	private ArithUtil() {

	}

	/**
	 * 提供精确的加法运算。
	 *
	 * @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();
	}

	public static double add(BigDecimal v1, BigDecimal v2,int scale) {
		BigDecimal b1 = v1.setScale(scale, BigDecimal.ROUND_HALF_DOWN);
		BigDecimal b2 = v2.setScale(scale, BigDecimal.ROUND_HALF_DOWN);
		return b1.add(b2).doubleValue();
	}
	/**
	 * 提供精确的减法运算。
	 *
	 * @param v1
	 *            被减数
	 * @param v2
	 *            减数
	 * @return 两个参数的差
	 */
	public static double sub(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.subtract(b2).doubleValue();
	}

	public static double sub(double v1, double v2,int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1)).setScale(scale, BigDecimal.ROUND_HALF_DOWN);
		BigDecimal b2 = new BigDecimal(Double.toString(v2)).setScale(scale, BigDecimal.ROUND_HALF_DOWN);
		return b1.subtract(b2).doubleValue();
	}
	/**
	 * 提供精确的乘法运算。
	 *
	 * @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();
	}

	/**
	 * 提供精确的乘法运算。
	 *
	 * @param v1
	 *            被乘数
	 * @param v2
	 *            乘数
	 * @return 两个参数的积
	 */
	public static double mul(double v1, double v2,int scale) {
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_DOWN).doubleValue();
	}
	/**
	 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
	 *
	 * @param v1
	 *            被除数
	 * @param v2
	 *            除数
	 * @return 两个参数的商
	 */
	public static double div(double v1, double v2) {
		return div(v1, v2, DEF_DIV_SCALE);
	}

	/**
	 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
	 *
	 * @param v1
	 *            被除数
	 * @param v2
	 *            除数
	 * @param scale
	 *            表示表示需要精确到小数点以后几位。
	 * @return 两个参数的商
	 */
	public static double div(double v1, double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("参数scale必须为整数为零!");
		}
		BigDecimal b1 = new BigDecimal(Double.toString(v1));
		BigDecimal b2 = new BigDecimal(Double.toString(v2));
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 提供精确的小数位四舍五入处理。
	 *
	 * @param v
	 *            需要四舍五入的数字
	 * @param scale
	 *            小数点后保留几位
	 * @return 四舍五入后的结果
	 */
	public static double round(double v, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException("参数scale必须为整数为零!");
		}
		BigDecimal b = new BigDecimal(Double.toString(v));
		BigDecimal one = new BigDecimal("1");
		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	/**
	 * 提供精确的类型转换(Float)
	 *
	 * @param v
	 *            需要被转换的数字
	 * @return 返回转换结果
	 */
	public static float convertsToFloat(double v) {
		BigDecimal b = new BigDecimal(v);
		return b.floatValue();
	}

	/**
	 * 提供精确的类型转换(Int)不进行四舍五入
	 *
	 * @param v
	 *            需要被转换的数字
	 * @return 返回转换结果
	 */
	public static int convertsToInt(double v) {
		BigDecimal b = new BigDecimal(v);
		return b.intValue();
	}

	/**
	 * 提供精确的类型转换(Long)
	 *
	 * @param v
	 *            需要被转换的数字
	 * @return 返回转换结果
	 */
	public static long convertsToLong(double v) {
		BigDecimal b = new BigDecimal(v);
		return b.longValue();
	}

	/**
	 * 返回两个数中大的一个值
	 *
	 * @param v1
	 *            需要被对比的第一个数
	 * @param v2
	 *            需要被对比的第二个数
	 * @return 返回两个数中大的一个值
	 */
	public static double returnMax(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.max(b2).doubleValue();
	}

	/**
	 * 返回两个数中小的一个值
	 *
	 * @param v1
	 *            需要被对比的第一个数
	 * @param v2
	 *            需要被对比的第二个数
	 * @return 返回两个数中小的一个值
	 */
	public static double returnMin(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.min(b2).doubleValue();
	}

	/**
	 * 精确比较两个数字
	 *
	 * @param v1
	 *            需要被对比的第一个数
	 * @param v2
	 *            需要被对比的第二个数
	 * @return 如果两个数一样则返回0,如果第一个数比第二个数大则返回1,反之返回-1
	 */
	public static int compareTo(double v1, double v2) {
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.compareTo(b2);
	}

	/**
	 * 获取数字小数位数
	 *
	 * @param number
	 *            数字.
	 *
	 * @return 小数位数
	 */
	public static int getDecimals(double number) {
		DecimalFormat decimalFormat = new DecimalFormat("#.####");
		String numberString = decimalFormat.format(number);
		if (numberString.indexOf(".") > 0) {
			return numberString.length() - String.valueOf(number).indexOf(".") - 1;
		} else {
			return 0;
		}
	}
	public static int getDecimals(String number) {
		if (number.indexOf(".") > 0) {
			return number.length() - String.valueOf(number).indexOf(".") - 1;
		} else {
			return 0;
		}
	}
	/**
	 * 获取数字小数位数
	 *
	 * @param number
	 *            数字.
	 *
	 * @return 小数位数
	 */
	public static int getDecimals(float number) {
		DecimalFormat decimalFormat = new DecimalFormat("#.####");
		String numberString = decimalFormat.format(number);
		if (numberString.indexOf(".") > 0) {
			return numberString.length() - String.valueOf(number).indexOf(".") - 1;
		} else {
			return 0;
		}
	}

	public static List<BigDecimal> getaverage(BigDecimal start,BigDecimal end ,int scale, int count){
		System.out.println("start"+start+",end"+end+",count"+count);
		String startStr = start.toString();
		String endstr = end.toString();
		BigDecimal subtract = end.subtract(start);
		List<BigDecimal> bibList = new ArrayList<>();
		//整数之间的运算
		if(startStr.indexOf(".") == -1 && startStr.indexOf(".") == -1 ){
			//整数之间相差 count数+1
			BigDecimal subtract2 = subtract.subtract(new BigDecimal(count+1));
			int compareTo = subtract2.compareTo(new BigDecimal(count+1));
			if(compareTo >= 0){
				BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1), 0, RoundingMode.FLOOR);
				System.out.println(compareTo +"公差 "+middleValue);
				for (int i = 1 ;i <= count; i ++){
					BigDecimal value = start.add(middleValue.multiply(new BigDecimal(i)));
					bibList.add(value);
				}
				System.out.println("==================");
				bibList.stream().forEach(a->System.out.println(a.toString()));
				return bibList;
			}else{
				StringBuffer bufferPoint = new StringBuffer();
				bufferPoint.append("0.");
				for(int i = 0 ; i < String.valueOf(count).length()-2 ;i ++){
					bufferPoint.append("0");
				}
				bufferPoint.append("1");
				BigDecimal subtract22 = subtract.subtract(new BigDecimal(count+1).multiply(new BigDecimal(bufferPoint.toString())));
				BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),subtract22.compareTo(new BigDecimal(0)) > 0 ? 1: String.valueOf(count).length(), RoundingMode.FLOOR);

				//可能出现升精度的问题
				System.out.println(compareTo +"公差 "+middleValue);
				for (int i = 1 ;i <= count; i ++){
					BigDecimal value = start.add(middleValue.multiply(new BigDecimal(i)));
					bibList.add(value);
				}
				System.out.println("==================");
				bibList.stream().forEach(a->System.out.println(a.toString()));
				return bibList;
			}

		}
		int startArith = startStr.indexOf(".") > 0 ? startStr.length() - startStr.indexOf(".") - 1 : 0;
		int endArith = startStr.indexOf(".") > 0 ? startStr.length() - startStr.indexOf(".") - 1 : 0;
		int max = Math.max(startArith,endArith);
		StringBuffer buffer = new StringBuffer();
		buffer.append("0.");
		for(int i = 0 ; i < max ;i ++){
			buffer.append("0");
		}
		buffer.append("1");
		BigDecimal subtract21 = subtract.subtract(new BigDecimal(count+1).multiply(new BigDecimal(buffer.toString())));
		
		//带小数的精度的运算
		BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),subtract21.compareTo(new BigDecimal(0)) > 0 ? max : max+String.valueOf(count).length()-1 , RoundingMode.FLOOR);
		//如果 > 0 升精度  小于0 升精度
//		int compareTo = middleValue.subtract(new BigDecimal(0)).compareTo(new BigDecimal(0));
//		if(compareTo > 0){
//			middleValue = subtract.divide(new BigDecimal(count + 1), max+1 , RoundingMode.FLOOR);
//		}
		System.out.println("公差 "+middleValue);
		for (int i = 1 ;i <= count; i ++){
			BigDecimal value = start.add(middleValue.multiply(new BigDecimal(i)));
			bibList.add(value);
		}
		System.out.println("==================");
		bibList.stream().forEach(a->System.out.println(a.toString()));
		return bibList;

	}
	public static List<BigDecimal> getlistArith(String starts,String ends , int count){
		System.out.println("start"+starts+",end"+ends+",count"+count);
		BigDecimal start = new BigDecimal(starts);
		BigDecimal end = new BigDecimal(ends);
		String startStr = start.toString();
		String endstr = end.toString();
		//如果剩的多
		int startArith = starts.indexOf(".") > 0 ? starts.length() - starts.indexOf(".") - 1 : 0;
		int endArith = ends.indexOf(".") > 0 ? ends.length() - ends.indexOf(".") - 1 : 0;
		int max = Math.max(startArith,endArith);
		StringBuffer buffer = new StringBuffer();
		
		BigDecimal subtract = end.subtract(start);
		int startArith1 = subtract.toPlainString().indexOf(".");
		String replace = subtract.toPlainString().replace(".", "");
		BigDecimal countRest = new BigDecimal(replace).subtract(new BigDecimal(count+1));
		int compareTo2 = countRest.compareTo(new BigDecimal(0));
		int maxArith = compareTo2 > 0 ?max : (count == 1 ? max+1:max + countRest.toPlainString().replace("-", "").length()+3);
		if(maxArith > 0){
			buffer.append("0.");
			for(int i = 0 ; i < maxArith-1 ;i ++){
				buffer.append("0");
			}
		}
		buffer.append("1");
		List<BigDecimal> bibList = new ArrayList<>();
		BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),maxArith, RoundingMode.FLOOR);
		
		for (int i = count ;i>=1; i--){
//			BigDecimal value = end.subtract(new BigDecimal(buffer.toString()).multiply(new BigDecimal(i)));
			BigDecimal value = end.subtract(new BigDecimal(middleValue.toPlainString()).multiply(new BigDecimal(i)));
			bibList.add(value);
		}
		System.out.println("==================");
		System.out.println(middleValue);
		bibList.stream().forEach(a->System.out.println(a.toString()));
		return bibList;
		
//		BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),compareTo2 > 0 ?max : max + countRest.toString().replace("-", "").length(), RoundingMode.FLOOR);
//		List<BigDecimal> bibList = new ArrayList<>();
//		
//		//可能出现升精度的问题
//		System.out.println(compareTo2 +"公差 "+middleValue);
//		for (int i = count ;i>=1; i--){
//			BigDecimal value = start.add(middleValue.multiply(new BigDecimal(i)));
//			bibList.add(value);
//		}
//		System.out.println("==================");
//		bibList.stream().forEach(a->System.out.println(a.toString()));
//		return bibList;

	}
	public static List<BigDecimal> getlistArithHead(String starts,String ends , int count){
		System.out.println("start"+starts+",end"+ends+",count"+count);
		BigDecimal start = new BigDecimal(starts);
		BigDecimal end = new BigDecimal(ends);
		String startStr = start.toString();
		String endstr = end.toString();
		//如果剩的多
		int startArith = starts.indexOf(".") > 0 ? starts.length() - starts.indexOf(".") - 1 : 0;
		int endArith = ends.indexOf(".") > 0 ? ends.length() - ends.indexOf(".") - 1 : 0;
		int max = Math.max(startArith,endArith);
		StringBuffer buffer = new StringBuffer();
		
		BigDecimal subtract = end.subtract(start);
		int startArith1 = subtract.toPlainString().indexOf(".");
		String replace = subtract.toPlainString().replace(".", "");
		BigDecimal countRest = new BigDecimal(replace).subtract(new BigDecimal(count+1));
		int compareTo2 = countRest.compareTo(new BigDecimal(0));
		int maxArith = compareTo2 > 0 ?max : (count == 1 ? max+1:max + countRest.toPlainString().replace("-", "").length()+3);
		if(maxArith > 0){
			buffer.append("0.");
			for(int i = 0 ; i < maxArith-1 ;i ++){
				buffer.append("0");
			}
		}
		buffer.append("1");
		List<BigDecimal> bibList = new ArrayList<>();
		BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),maxArith, RoundingMode.FLOOR);
		
		for (int i = count ;i>=1; i--){
			BigDecimal value = end.subtract(new BigDecimal(buffer.toString()).multiply(new BigDecimal(i)));
//			BigDecimal value = end.subtract(new BigDecimal(middleValue.toPlainString()).multiply(new BigDecimal(i)));
			bibList.add(value);
		}
		System.out.println("==================");
		System.out.println(middleValue);
		bibList.stream().forEach(a->System.out.println(a.toString()));
		return bibList;
		
//		BigDecimal middleValue = subtract.divide(new BigDecimal(count + 1),compareTo2 > 0 ?max : max + countRest.toString().replace("-", "").length(), RoundingMode.FLOOR);
//		List<BigDecimal> bibList = new ArrayList<>();
//		
//		//可能出现升精度的问题
//		System.out.println(compareTo2 +"公差 "+middleValue);
//		for (int i = count ;i>=1; i--){
//			BigDecimal value = start.add(middleValue.multiply(new BigDecimal(i)));
//			bibList.add(value);
//		}
//		System.out.println("==================");
//		bibList.stream().forEach(a->System.out.println(a.toString()));
//		return bibList;

	}
	public static void main(String[] args) {
//		getlistTable("1.00019996998999","1.00019997",0,1);
		String start = "1";
		String end = "2";
		for (int i = 0; i < 100; i++) {
			List<BigDecimal> getlistTable = getlistArith(start,end,1);
			start = getlistTable.get(0).toString();
			System.out.println(end);
		}

	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值