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 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 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 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 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 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 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 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 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 getlistTable = getlistArith(start,end,1);
start = getlistTable.get(0).toString();
System.out.println(end);
}
}
}