版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zuo_er_lyf/article/details/85263057
谈到四舍五入都不陌生,BigDecimal和DecmalFormat,是不是很熟悉,给2个例子,看下结果:
BigDecimal b = new BigDecimal("0.045");
double num1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
BigDecimal b = new BigDecimal("0.055");
double num2 = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
LogUtils.e("四舍五入","num1: "+ num1 + " num2: "+ num2);
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
double num3=Double.parseDouble(decimalFormat.format("0.045"));
double num4=Double.parseDouble(decimalFormat.format("0.055"));
LogUtils.e("四舍五入","num3: "+ num3 + " num4: "+ num4);
预测结果:
num1: 0.05 num2: 0.06
num3: 0.05 num4: 0.06
实际打印结果:
num1: 0.04 num2: 0.06
num3: 0.04 num4: 0.06
是不是有点懵逼 - _ -,没关系,来看一看api:
1、ROUND_UP:远离零方向舍入。向绝对值最大的方向舍入,只要舍弃位非0即进位。
2、ROUND_DOWN:趋向零方向舍入。向绝对值最小的方向输入,所有的位都要舍弃,不存在进位情况。
3、ROUND_CEILING:向正无穷方向舍入。向正最大方向靠拢。若是正数,舍入行为类似于ROUND_UP,若为负数,舍入行为类似于ROUND_DOWN。Math.round()方法就是使用的此模式。
4、ROUND_FLOOR:向负无穷方向舍入。向负无穷方向靠拢。若是正数,舍入行为类似于ROUND_DOWN;若为负数,舍入行为类似于ROUND_UP。
5、 HALF_UP:最近数字舍入(5进)。这是我们最经典的四舍五入。
6、 HALF_DOWN:最近数字舍入(5舍)。在这里5是要舍弃的。
7、 HAIL_EVEN:银行家舍入法
舍去位的数值小于5时,直接舍去。 舍去位的数值大于5时,进位后舍去。
当舍去位的数值等于5时,若5后面还有其他非0数值,则进位后舍去,若5后面是0时,则根据5前一位数的奇偶性来判断,奇数进位,偶数舍去。
对于上面的规则我们举例说明
11.556 = 11.56 ——六入
11.554 = 11.55 —–四舍
11.5551 = 11.56 —–五后有数进位
11.545 = 11.54 —–五后无数,若前位为偶数应舍去
11.555 = 11.56 —–五后无数,若前位为奇数应进位、
于是上面的测试改成了如下:
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
double num3=Double.parseDouble(decimalFormat.format("0.045"));
double num4=Double.parseDouble(decimalFormat.format("0.055"));
LogUtils.e("四舍五入","num3: "+ num3 + " num4: "+ num4);
结果:
num3: 0.05 num4: 0.06
注:如果传入的数值市浮点型:
DecimalFormat decimalFormat = new DecimalFormat("#0.00");
decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
double num3=Double.parseDouble(decimalFormat.format(0.045f));
double num4=Double.parseDouble(decimalFormat.format(0.055f));
LogUtils.e("四舍五入","num3: "+ num3 + " num4: "+ num4);
结果:
num3: 0.05 num4: 0.05
原因:
源码分析:
public final String format(double value) {
return format(value, new StringBuffer(), new FieldPosition(0)).toString();
}
只支持double类型的,但是我写float类型也不会报错,他会默认将float类型转为double类型,强转的话很容易导致进度丢失。
解决方法封装:
/**
* 四舍五入
* @param v 要传入的数值
* @param scale 例:2位小数 "#0.00"
* @return
*/
public static String roundByScale(String v, String scale) {
BigDecimal d = new BigDecimal(String.valueOf(v));
DecimalFormat decimalFormat = new DecimalFormat(scale);
decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
return decimalFormat.format(d.doubleValue());
}
引入了BigDecimal来将float转为double型:
public BigDecimal(String val) {
this(val.toCharArray(), 0, val.length());
}