谈一谈四舍五入

版权声明:本文为博主原创文章,未经博主允许不得转载。 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());
    }

猜你喜欢

转载自blog.csdn.net/zuo_er_lyf/article/details/85263057
今日推荐