java中进行浮点数运算时由于计算机底层运算问题可能导致精度丢失,例如:
double d1 = 0.3;
double d2 = 0.2;
System.out.println(d1 - d2);//0.199999999999998
针对以上算术运算预期值应该是:0.2,但是实际结果确是:0.19999999999999998;如果用于表示金额等敏感数值则可能引起极大错误,因此对于精度要求较高的浮点数运算时,通常使用BigDecimal类型处理,具体如下:
BigDecimal d1 = new BigDecimal("0.3");
BigDecimal d2 = new BigDecimal("0.1");
//相加
BigDecimal add = d1.add(d2));
//相减
BigDecimal subtract = d1.subtract(d2);
//相乘
BigDecimal multiply = d1.multiply(d2);
//相除
BigDecimal div = d1.divide(d2);
//取余
System.out.println(d1.remainder(d2));
/*针对以上相除运算如果反过来使用d2处以d1则会导致小数点后无穷大,从而引发ArithmeticException异常,
因此针对以上问题,应该采用
divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
divisor 表示除数
scale 精度(小数点后保留位数)
roundingMode 舍入模式
方法设置数值精度来避免异常,如下:
*/
BigDecimal div2 = d2.divide(d1,2,RoundingMode.HALF_UP);
//针对以上结果若想转化为其他基本数据类型则可使用以下方法解决:
//div2.intValue()
//div2.doubleValue()
//...
在表示一个数值时通常根据项目的不同需求可能需要显示为不同的格式,比如:货币,百分比等,此时可以通过NumberFormat&DecimalFormat进行解决,如下:
double d = 432765123.89653;
//使用标准显示格式
String s = NumberFormat.getInstance().format(d);//结果:432,765,123.897
//显示为货币格式
s = NumberFormat.getCurrencyInstance().format(d);//结果:¥432,765,123.897
d = 0.5456;
//显示为百分比
s = NumberFormat.getPercentInstance().format(d);//结果:54%
以上为默认的数值格式化工具,但是针对某些特定需求(比如数值d要求保留小数点后两位,默认为3位;百分比值要求保留一位小数,默认取整),默认的格式化工具可能无法完全满足需求,此时可以通过DecimalFormat定制个性化需求:
double d = 432765123.88653;
DecimalFormat fmt = new DecimalFormat("##,###.##");
fmt.format(d);//结果:432,765,123.89
double d = 0.5456
DecimalFormat fmt = new DecimalFormat("##.#%");
fmt.format(d);//结果:54.6%