当前位置: 首页 > article >正文

线上慎用 BigDecimal ,坑的差点被开了

Java在java.math包中提供的API类BigDecimal用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数但在实际应用中可能需要对更大或者更小的数进行运算和处理。一般情况下对于那些不需要准确计算精度的数字我们可以直接使用Float和Double处理但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中如果我们需要精确计算的结果则必须使用BigDecimal类来操作。BigDecimal所创建的是对象故我们不能使用传统的、-、*、/等算术运算符直接对其对象进行数学运算而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法专门用来创建对象特别是带有参数的对象。BigDecimal常用构造函数1、常用构造函数BigDecimal(int)创建一个具有参数所指定整数值的对象BigDecimal(double)创建一个具有参数所指定双精度值的对象BigDecimal(long)创建一个具有参数所指定长整数值的对象BigDecimal(String)创建一个具有参数所指定以字符串表示的数值的对象2、使用问题分析使用示例BigDecimal a new BigDecimal(0.1); System.out.println(a values is:a); System.out.println(); BigDecimal b new BigDecimal(0.1); System.out.println(b values is:b);结果示例a values is:0.1000000000000000055511151231257827021181583404541015625 b values is:0.1原因分析1参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1非标度值 1其标度为 1但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double或者说对于该情况不能表示为任何有限长度的二进制小数。这样传入到构造方法的值不会正好等于 0.1虽然表面上等于该值。2String 构造方法是完全可预知的写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal它正好等于预期的 0.1。因此比较而言 通常建议优先使用String构造方法。3当double必须用作BigDecimal的源时请注意此构造方法提供了一个准确转换它不提供与以下操作相同的结果先使用Double.toString(double)方法然后使用BigDecimal(String)构造方法将double转换为String。要获取该结果请使用static valueOf(double)方法。BigDecimal常用方法详解1、常用方法add(BigDecimal)BigDecimal对象中的值相加返回BigDecimal对象subtract(BigDecimal)BigDecimal对象中的值相减返回BigDecimal对象multiply(BigDecimal)BigDecimal对象中的值相乘返回BigDecimal对象divide(BigDecimal)BigDecimal对象中的值相除返回BigDecimal对象toString()将BigDecimal对象中的值转换成字符串doubleValue()将BigDecimal对象中的值转换成双精度数floatValue()将BigDecimal对象中的值转换成单精度数longValue()将BigDecimal对象中的值转换成长整数intValue()将BigDecimal对象中的值转换成整数2、BigDecimal大小比较java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法int a bigdemical.compareTo(bigdemical2)返回结果分析a -1,表示bigdemical小于bigdemical2 a 0,表示bigdemical等于bigdemical2 a 1,表示bigdemical大于bigdemical2举例a大于等于bnew bigdemica(a).compareTo(new bigdemical(b)) 0BigDecimal格式化由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数可以利用BigDecimal对超出16位有效数字的货币值百分值以及一般数值进行格式化控制。以利用BigDecimal对货币和百分比格式化为例。首先创建BigDecimal对象进行BigDecimal的算术运算后分别建立对货币和百分比格式化的引用最后利用BigDecimal对象作为format()方法的参数输出其格式化的货币值和百分比。NumberFormat currency NumberFormat.getCurrencyInstance(); //建立货币格式化引用 NumberFormat percent NumberFormat.getPercentInstance(); //建立百分比格式化引用 percent.setMaximumFractionDigits(3); //百分比小数点最多3位 BigDecimal loanAmount new BigDecimal(15000.48); //贷款金额 BigDecimal interestRate new BigDecimal(0.008); //利率 BigDecimal interest loanAmount.multiply(interestRate); //相乘 System.out.println(贷款金额:\t currency.format(loanAmount)); System.out.println(利率:\t percent.format(interestRate)); System.out.println(利息:\t currency.format(interest));结果贷款金额: 15,000.48 利率: 0.8% 利息: 120.00BigDecimal格式化保留2为小数不足则补0public class NumberFormat { public static void main(String[] s){ System.out.println(formatToNumber(new BigDecimal(3.435))); System.out.println(formatToNumber(new BigDecimal(0))); System.out.println(formatToNumber(new BigDecimal(0.00))); System.out.println(formatToNumber(new BigDecimal(0.001))); System.out.println(formatToNumber(new BigDecimal(0.006))); System.out.println(formatToNumber(new BigDecimal(0.206))); } /** * desc 1.0~1之间的BigDecimal小数格式化后失去前面的0,则前面直接加上0。 * 2.传入的参数等于0则直接返回字符串0.00 * 3.大于1的小数直接格式化返回字符串 * param obj传入的小数 * return */ public static String formatToNumber(BigDecimal obj) { DecimalFormat df new DecimalFormat(#.00); if(obj.compareTo(BigDecimal.ZERO)0) { return0.00; }elseif(obj.compareTo(BigDecimal.ZERO)0obj.compareTo(new BigDecimal(1))0){ return0df.format(obj).toString(); }else { return df.format(obj).toString(); } } }结果为3.44 0.00 0.00 0.00 0.01 0.21BigDecimal常见异常除法的时候出现异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result原因分析通过BigDecimal的divide方法进行除法时当不整除出现无限循环小数时就会抛异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.解决方法divide方法设置精确的小数点如divide(xxxxx,2)BigDecimal总结1、总结在需要精确的小数计算时再使用BigDecimalBigDecimal的性能比double和float差在处理庞大复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。 尽量使用参数类型为String的构造函数。BigDecimal都是不可变的immutable的 在进行每一次四则运算时都会产生一个新的对象 所以在做加减乘除运算时要记得要保存操作后的值。2、工具类推荐package com.vivo.ars.util; import java.math.BigDecimal; /** * 用于高精确处理常用的数学运算 */ publicclass ArithmeticUtils { //默认除法运算精度 privatestaticfinalint 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) { thrownew 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 sub(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 sub(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 sub(String v1, String v2, int scale) { if (scale 0) { thrownew 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 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 BigDecimal mul(String v1, String v2) { BigDecimal b1 new BigDecimal(v1); BigDecimal b2 new BigDecimal(v2); return b1.multiply(b2); } /** * 提供精确的乘法运算 * * param v1 被乘数 * param v2 乘数 * param scale 保留scale 位小数 * 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 round(b1.multiply(b2).doubleValue(), scale); } /** * 提供精确的乘法运算 * * param v1 被乘数 * param v2 乘数 * param scale 保留scale 位小数 * return 两个参数的积 */ public static String mul(String v1, String v2, int scale) { if (scale 0) { thrownew 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 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) { thrownew 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 div(String v1, String v2, int scale) { if (scale 0) { thrownew 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) { thrownew IllegalArgumentException(The scale must be a positive integer or zero); } BigDecimal b new BigDecimal(Double.toString(v)); return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理 * * param v 需要四舍五入的数字 * param scale 小数点后保留几位 * return 四舍五入后的结果 */ public static String round(String v, int scale) { if (scale 0) { thrownew 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) { thrownew 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) { thrownew IllegalArgumentException( The scale must be a positive integer or zero); } return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); } /** * 比较大小 * * param v1 被比较数 * param v2 比较数 * return 如果v1 大于v2 则 返回true 否则false */ public static boolean compare(String v1, String v2) { BigDecimal b1 new BigDecimal(v1); BigDecimal b2 new BigDecimal(v2); int bj b1.compareTo(b2); boolean res; if (bj 0) res true; else res false; return res; } }来源cnblogs.com/zhangyinhua/p/11545305.htmlJava在java.math包中提供的API类BigDecimal用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数但在实际应用中可能需要对更大或者更小的数进行运算和处理。一般情况下对于那些不需要准确计算精度的数字我们可以直接使用Float和Double处理但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中如果我们需要精确计算的结果则必须使用BigDecimal类来操作。BigDecimal所创建的是对象故我们不能使用传统的、-、*、/等算术运算符直接对其对象进行数学运算而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法专门用来创建对象特别是带有参数的对象。BigDecimal常用构造函数1、常用构造函数BigDecimal(int)创建一个具有参数所指定整数值的对象BigDecimal(double)创建一个具有参数所指定双精度值的对象BigDecimal(long)创建一个具有参数所指定长整数值的对象BigDecimal(String)创建一个具有参数所指定以字符串表示的数值的对象2、使用问题分析使用示例BigDecimal a new BigDecimal(0.1); System.out.println(a values is:a); System.out.println(); BigDecimal b new BigDecimal(0.1); System.out.println(b values is:b);结果示例a values is:0.1000000000000000055511151231257827021181583404541015625 b values is:0.1原因分析1参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1非标度值 1其标度为 1但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double或者说对于该情况不能表示为任何有限长度的二进制小数。这样传入到构造方法的值不会正好等于 0.1虽然表面上等于该值。2String 构造方法是完全可预知的写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal它正好等于预期的 0.1。因此比较而言 通常建议优先使用String构造方法。3当double必须用作BigDecimal的源时请注意此构造方法提供了一个准确转换它不提供与以下操作相同的结果先使用Double.toString(double)方法然后使用BigDecimal(String)构造方法将double转换为String。要获取该结果请使用static valueOf(double)方法。BigDecimal常用方法详解1、常用方法add(BigDecimal)BigDecimal对象中的值相加返回BigDecimal对象subtract(BigDecimal)BigDecimal对象中的值相减返回BigDecimal对象multiply(BigDecimal)BigDecimal对象中的值相乘返回BigDecimal对象divide(BigDecimal)BigDecimal对象中的值相除返回BigDecimal对象toString()将BigDecimal对象中的值转换成字符串doubleValue()将BigDecimal对象中的值转换成双精度数floatValue()将BigDecimal对象中的值转换成单精度数longValue()将BigDecimal对象中的值转换成长整数intValue()将BigDecimal对象中的值转换成整数2、BigDecimal大小比较java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法int a bigdemical.compareTo(bigdemical2)返回结果分析a -1,表示bigdemical小于bigdemical2 a 0,表示bigdemical等于bigdemical2 a 1,表示bigdemical大于bigdemical2举例a大于等于bnew bigdemica(a).compareTo(new bigdemical(b)) 0BigDecimal格式化由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数可以利用BigDecimal对超出16位有效数字的货币值百分值以及一般数值进行格式化控制。以利用BigDecimal对货币和百分比格式化为例。首先创建BigDecimal对象进行BigDecimal的算术运算后分别建立对货币和百分比格式化的引用最后利用BigDecimal对象作为format()方法的参数输出其格式化的货币值和百分比。NumberFormat currency NumberFormat.getCurrencyInstance(); //建立货币格式化引用 NumberFormat percent NumberFormat.getPercentInstance(); //建立百分比格式化引用 percent.setMaximumFractionDigits(3); //百分比小数点最多3位 BigDecimal loanAmount new BigDecimal(15000.48); //贷款金额 BigDecimal interestRate new BigDecimal(0.008); //利率 BigDecimal interest loanAmount.multiply(interestRate); //相乘 System.out.println(贷款金额:\t currency.format(loanAmount)); System.out.println(利率:\t percent.format(interestRate)); System.out.println(利息:\t currency.format(interest));结果贷款金额: 15,000.48 利率: 0.8% 利息: 120.00BigDecimal格式化保留2为小数不足则补0public class NumberFormat { public static void main(String[] s){ System.out.println(formatToNumber(new BigDecimal(3.435))); System.out.println(formatToNumber(new BigDecimal(0))); System.out.println(formatToNumber(new BigDecimal(0.00))); System.out.println(formatToNumber(new BigDecimal(0.001))); System.out.println(formatToNumber(new BigDecimal(0.006))); System.out.println(formatToNumber(new BigDecimal(0.206))); } /** * desc 1.0~1之间的BigDecimal小数格式化后失去前面的0,则前面直接加上0。 * 2.传入的参数等于0则直接返回字符串0.00 * 3.大于1的小数直接格式化返回字符串 * param obj传入的小数 * return */ public static String formatToNumber(BigDecimal obj) { DecimalFormat df new DecimalFormat(#.00); if(obj.compareTo(BigDecimal.ZERO)0) { return0.00; }elseif(obj.compareTo(BigDecimal.ZERO)0obj.compareTo(new BigDecimal(1))0){ return0df.format(obj).toString(); }else { return df.format(obj).toString(); } } }结果为3.44 0.00 0.00 0.00 0.01 0.21BigDecimal常见异常除法的时候出现异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result原因分析通过BigDecimal的divide方法进行除法时当不整除出现无限循环小数时就会抛异常java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.解决方法divide方法设置精确的小数点如divide(xxxxx,2)BigDecimal总结1、总结在需要精确的小数计算时再使用BigDecimalBigDecimal的性能比double和float差在处理庞大复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。 尽量使用参数类型为String的构造函数。BigDecimal都是不可变的immutable的 在进行每一次四则运算时都会产生一个新的对象 所以在做加减乘除运算时要记得要保存操作后的值。2、工具类推荐package com.vivo.ars.util; import java.math.BigDecimal; /** * 用于高精确处理常用的数学运算 */ publicclass ArithmeticUtils { //默认除法运算精度 privatestaticfinalint 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) { thrownew 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 sub(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 sub(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 sub(String v1, String v2, int scale) { if (scale 0) { thrownew 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 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 BigDecimal mul(String v1, String v2) { BigDecimal b1 new BigDecimal(v1); BigDecimal b2 new BigDecimal(v2); return b1.multiply(b2); } /** * 提供精确的乘法运算 * * param v1 被乘数 * param v2 乘数 * param scale 保留scale 位小数 * 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 round(b1.multiply(b2).doubleValue(), scale); } /** * 提供精确的乘法运算 * * param v1 被乘数 * param v2 乘数 * param scale 保留scale 位小数 * return 两个参数的积 */ public static String mul(String v1, String v2, int scale) { if (scale 0) { thrownew 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 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) { thrownew 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 div(String v1, String v2, int scale) { if (scale 0) { thrownew 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) { thrownew IllegalArgumentException(The scale must be a positive integer or zero); } BigDecimal b new BigDecimal(Double.toString(v)); return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确的小数位四舍五入处理 * * param v 需要四舍五入的数字 * param scale 小数点后保留几位 * return 四舍五入后的结果 */ public static String round(String v, int scale) { if (scale 0) { thrownew 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) { thrownew 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) { thrownew IllegalArgumentException( The scale must be a positive integer or zero); } return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP); } /** * 比较大小 * * param v1 被比较数 * param v2 比较数 * return 如果v1 大于v2 则 返回true 否则false */ public static boolean compare(String v1, String v2) { BigDecimal b1 new BigDecimal(v1); BigDecimal b2 new BigDecimal(v2); int bj b1.compareTo(b2); boolean res; if (bj 0) res true; else res false; return res; } }来源cnblogs.com/zhangyinhua/p/11545305.html

相关文章:

线上慎用 BigDecimal ,坑的差点被开了

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算…...

RPFM v4.7.102:Total War MOD开发工具的技术架构重构与性能优化

RPFM v4.7.102:Total War MOD开发工具的技术架构重构与性能优化 【免费下载链接】rpfm Rusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt5 of PackFile Manager (PFM), one of the best modding tools for Total War Games. 项目地址: ht…...

算法基础|双指针核心思想与应用

今天复习双指针技巧,整理一下核心思路和典型用法。双指针是笔试面试中非常高频的算法思想,能把很多问题的时间复杂度从 O (n) 优化到 O (n)。 目录 一、核心思想 二、典型应用场景 三、例题实战 四、考点提炼 一、核心思想 用两个指针分别指向数组…...

大咖集结·即刻报名 | 2026 玄铁 RISC-V 生态大会主论坛议程正式发布!

2026 年 3 月 24 日,“开放连接” 2026 玄铁 RISC-V 生态大会将在上海世博桐森酒店盛大启幕。主论坛议程现已正式发布,立即扫描下方海报二维码报名。期待与大家再聚申城,春暖花开,共启芯篇! 扫码报名,到现场…...

电脑驱动配置全攻略

电脑驱动配置指南大纲驱动配置的基本概念驱动的定义与作用驱动与硬件、操作系统的关系常见驱动类型(显卡驱动、声卡驱动、网卡驱动等)驱动获取的途径官方渠道(制造商官网、OEM 支持页面)操作系统内置驱动(Windows Upda…...

Z-Image-Turbo实战教程:用ControlNet扩展支持草图引导生成

Z-Image-Turbo实战教程:用ControlNet扩展支持草图引导生成 1. 引言:从文字到画面的精准控制 想象一下,你脑海中有一个非常具体的画面:一座未来感十足的悬浮城堡,有着特定的轮廓和结构。你尝试用文字描述它&#xff0…...

新手前端入门实战:跟快马AI学用JavaScript实现游戏cc switch效果

最近在学前端,想找个有趣的小项目练手,正好看到游戏里“角色切换”这个交互,感觉挺适合用来理解事件处理和DOM操作。于是,我决定用最基础的HTML、CSS和JavaScript来模拟一个类似《原神》的角色切换效果。整个过程下来,…...

工业质检应用:为黑白缺陷图像着色以增强识别

工业质检应用:为黑白缺陷图像着色以增强识别 在工厂的流水线旁,质检员小王正紧盯着屏幕上一张张高速闪过的零件图像。这些图像来自产线上的黑白工业相机,清晰度没问题,但总有些细节——比如金属表面的细微划痕、塑料件上的微小气…...

软件测试技术沉淀之常用SQL语句

涉及工具:NavicatSQL语句(CRUD)一、增insert into 表名(字段名) values (内容列表)insert into student values (S0013,男,18) insert into SC(Sno,Cno) values(S0013,C005)二、删delete from 表名 where 条件delete f…...

DGUS屏开发实战:从工程下载到UI界面设计全解析

1. DGUS屏开发环境搭建 第一次接触DGUS屏开发时,最让人头疼的就是环境配置。记得我第一次拿到DGUS屏时,光是SD卡格式化就折腾了半天。后来才发现,这里面的门道还真不少。 SD卡格式化是第一步,但很多人容易忽略细节。我建议使用容量…...

如何永久重置IDM试用期:深度技术解析与实战部署指南

如何永久重置IDM试用期:深度技术解析与实战部署指南 【免费下载链接】idm-trial-reset Use IDM forever without cracking 项目地址: https://gitcode.com/gh_mirrors/id/idm-trial-reset 你是否曾因IDM试用期到期而困扰?为何简单的注册表清理无法…...

隐私新防线:本地化处理如何终结大数据窃听时代?

当AI修图、语音转写、智能办公成为日常,我们的自拍照、通话录音、工作文档等隐私数据,正通过云端传输沦为“窃听”目标。大数据窃听的核心症结,在于数据需上传至远程服务器处理,传输与存储过程中易被拦截、滥用,而本地…...

Codescene 实战指南:如何通过热点分析提升代码质量

1. 为什么你的代码库需要热点分析 想象一下你刚接手一个遗留系统,面对几十万行代码,最头疼的问题是什么?是不知道从哪里开始优化。我经历过无数次这种场景,直到发现Codescene的热点分析功能——它就像给代码库做了个CT扫描&#x…...

MinIO + Nginx 搭建企业级文件服务

在上一篇中,我们已经完成了 MinIO 的基础搭建,可以实现对象存储的上传与下载。 但如果你真的打算在公司里用起来,还差关键一步:让它变成一个“对外可用、稳定、安全”的文件服务。这一篇,我们重点讲: 为什么…...

用Quartus II 13.0+VHDL实现数字电路仿真:一位加法器实战教学

用Quartus II 13.0VHDL实现数字电路仿真:一位加法器实战教学 在FPGA开发领域,理解从代码到实际硬件电路的完整流程是每个工程师的必修课。本文将带您深入探索如何通过Quartus II 13.0这一经典工具,用VHDL语言实现一位加法器的设计与仿真。不同…...

Loomy来了!人人可用的AI工作搭子

Loomy是讯飞推出的基于 AstroncClaw 打造的桌面级助理,主打本地办公场景Skills,同时支持用户自定义的SkillHub,面向全球生态开放共享。 今天,Loomy 正式上线,人人可用的桌面版「OpenClaw」! 作为一个“有性…...

10大滴鸡精品牌推荐排行榜

大家好,今天我要和大家聊聊一个热门话题——滴鸡精。在快节奏的生活中,越来越多的人开始注重养生保健,滴鸡精作为一种方便快捷的滋补品,受到了很多人的青睐。不过市场上的滴鸡精品牌琳琅满目,到底哪些品牌更值得信赖呢…...

Qwen2.5-72B-GPTQ-Int4快速上手:10分钟完成72B大模型镜像免配置部署

Qwen2.5-72B-GPTQ-Int4快速上手:10分钟完成72B大模型镜像免配置部署 想体验一下720亿参数大模型的强大能力,但又担心部署过程复杂、配置繁琐?今天,我们就来彻底解决这个问题。 我将带你快速上手一个已经打包好的Qwen2.5-72B-Ins…...

食品厂一年省出一辆宝马?这个“黑盒子”让冷库电费砍一半

“夏天电费又涨了,冷库压缩机整天转,电表跑得比秒针还快……”这是很多食品厂老板的痛点。尤其做烘焙、肉制品、水果加工的,冷库是命根子,也是电费的大头。更扎心的是——你可能一直在花冤枉钱。绝大多数食品厂冷库,现…...

集成电路封装基板技术:从传统到埋嵌芯片的演进与应用

1. 集成电路封装基板技术的前世今生 记得我第一次拆解老式收音机时,被里面密密麻麻的导线和硕大的电子元件震惊了。而如今,一部智能手机的运算能力是当年阿波罗登月计算机的百万倍,体积却只有巴掌大小。这种惊人的进化,很大程度上…...

Java 四种引用:强、软、弱、虚

在 Java 中,并不是所有对象都只有 “存活” 和 “死亡” 两种状态。通过不同强度的引用,我们可以让 GC 灵活决定对象的生命周期,这也是面试、缓存设计、内存优化中的高频考点。一、为什么要有四种引用?Java 最开始只有强引用&…...

改善快讯——北汇信息第五期业务骨干OBS训练营

2026 年 3 月7 日,北汇信息成功举办了第五期OBS训练营。新成立的交付中心和现场服务BU的业务骨干们齐聚北汇宁波分公司,体验学习OBS相关知识与工具,提升工作效率与团队协作能力,为自己和团队的进一步成长打下了良好的基础。本次活…...

华为OpenEuler实战指南(04)--Win10与openEuler双系统安装与优化

1. 双系统安装前的准备工作 在华为笔记本上安装openEuler和Win10双系统,第一步不是急着插U盘,而是要做好充分的准备工作。我见过太多人因为跳过准备步骤,导致安装过程中数据丢失或系统崩溃。根据我的经验,至少需要预留3小时完整时…...

因果瓦片归因:视觉模型的结构化与忠实解释

摘要 深度视觉模型的事后解释通常是在像素级别生成的,尽管现代架构和推理流程越来越多地基于诸如块、窗口和瓦片(tiles)这样的结构化单元进行操作。这种解释单元与计算单元之间的错位,常常导致生成的解释充满噪声、脆弱,并且在高风险场景下难以审查。我们提出了因果瓦片归…...

OpenClaw 配置 MiniMax M2.5 避坑指南

OpenClaw2026.3.13 配置 MiniMax M2.5 避坑指南═══════════════════════════════════════════════════════════════一、套餐说明MiniMax Coding Plan(开发套餐) ├─ Starter 月度套餐&…...

开源GUI编辑器lopaka发布V0.6版本,增加LVGL支持,同时支持 TFT_eSPI,U8g2,AdafruitGFX,Flipper Zero等

https://github.com/sbrin/lopaka?tabreadme-ov-file 更新记录: Lopaka 是一款开源图形编辑器,旨在为 TFT_eSPI、U8g2、AdafruitGFX 和 Flipper Zero 提供图形创建界面。它与 M5GFX、LovyanGFX、Watchy 等多种平台兼容。绘制任意图形,并将…...

Poppins开源字体:企业级多语言排版解决方案的商业价值深度分析

Poppins开源字体:企业级多语言排版解决方案的商业价值深度分析 【免费下载链接】Poppins Poppins, a Devanagari Latin family for Google Fonts. 项目地址: https://gitcode.com/gh_mirrors/po/Poppins 在全球化数字产品设计中,Poppins开源字体…...

灵毓秀-牧神-造相Z-Turbo与SpringBoot集成:打造智能文生图API服务

灵毓秀-牧神-造相Z-Turbo与SpringBoot集成:打造智能文生图API服务 本文介绍了如何将灵毓秀-牧神-造相Z-Turbo文生图模型集成到SpringBoot框架中,构建高效、易用的RESTful API服务,让开发者能够快速为应用添加智能图像生成能力。 1. 为什么需要…...

边缘计算在数据采集方面的应用可行性分析

一、边缘计算可行性分析及模块选择 1. 边缘计算核心价值适配场景 边缘计算的核心价值在于本地预处理、实时响应、降低云端带宽、离线可用,这与数据采集相关产品使用场景高度契合: 大型结构长期监测(风电、杆塔、储罐)&#xff…...

Ubuntu 20.04 LTS下AirSim+UE4.27环境搭建避坑指南(附百度网盘资源)

Ubuntu 20.04 LTS下AirSim与UE4.27开发环境高效部署实战 在无人机仿真开发领域,Linux平台因其稳定性和高效性备受开发者青睐。然而,当技术栈涉及虚幻引擎(UE)和AirSim这样的复杂工具链时,环境搭建往往成为项目启动的第一道门槛。本文将分享一…...