我想使用java的某种数据类型实现舍入功能。据说及多年的编程经验,发现Float和Double类型在精度上不够,如0.1,它可能表示成0.9999999999之类的。所以,我使用BigDecimal。但是,在四舍五入方面,我看了BigDecimal的文档,感觉问题多多?废话少说,看下面例子:
BigDecimal a =
new BigDecimal(99.215).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(a);

BigDecimal b =
new BigDecimal(99.115).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(b);

BigDecimal c =
new BigDecimal(99.215).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(c);
大家说上面的例子输出结果是什么?答案是:99.22,99.11,99.22。可为什么第个结果不是99.12呢?如果才能达到中国人理想中的四舍五入?

解决方案 »

  1.   

    /**
         * 提供精确的小数位四舍五入处理。     * @param v 需要四舍五入的数字     * @param scale 小数点后保留几位     * @return 四舍五入后的结果     */    public static double round(double v, int scale)
        {        if (scale < 0)
            {            throw new IllegalArgumentException(                "The scale must be a positive integer or zero");        }        BigDecimal b = new BigDecimal(Double.toString(v));        BigDecimal one = new BigDecimal("1");        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();    }
      

  2.   

    因为你是直接用数字构造的BigDecimal(99.115),但是数字本身就是不能精确表示的,当然构造的BigDecimal对象也就是不精确的,如果用数字的字符串形式就能正确表示了;
    BigDecimal a = new BigDecimal("99.215").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(a); BigDecimal b = new BigDecimal("99.115").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(b); BigDecimal c = new BigDecimal("99.215").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(c);
      

  3.   

    用字符串就没有问题
    BigDecimal a = new BigDecimal("99.215").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(a); BigDecimal b = new BigDecimal("99.115").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(b); BigDecimal c = new BigDecimal("99.215").setScale(2,
    BigDecimal.ROUND_HALF_UP);
    System.out.println(c);
      

  4.   

    http://www.it286.net/ProgramDevelop/java/200606/20641.html