本帖最后由 tianhama 于 2009-08-27 18:40:37 编辑

解决方案 »

  1.   

    楼主,看了你的问题,我去看了看网上的说法,把Double转换成String
    用BigDecimal(String value)这个构造方法BigDecimal在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关心用BigInteger来够造的那两个,那么还有两个,它们是:BigDecimal(double val)          Translates a double into a BigDecimal.BigDecimal(String val)          Translates the String repre sentation of a BigDecimal into a BigDecimal.上面的API简要描述相当的明确,而且通常情况下,上面的那一个使用起来要方便一些。我们可能想都不想就用上了,会有什么问题呢?等到出了问题的时候,才发现上面哪个够造方法的详细说明中有这么一段:Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧
    摘自 :http://blog.csdn.net/fenglibing/archive/2007/08/30/1765187.aspx 请参考
      

  2.   

    new BigDecimal(0.01995)
    在机子里变成0.01994999999999999999999999999999了
      

  3.   

    RoundingMode.HALF_EVEN-----如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同(入);如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同(舍)。是的。。应该是0.0200才对
    double d_value = 0.01995;
    String s_value = String.valueOf(d_value);System.out.println("before:"+s_value);
    System.out.println("after:"+new BigDecimal(s_value).setScale(4,
                RoundingMode.HALF_EVEN));
    output : 
            before:0.01995
            after:0.0200我想是验证了这句话 ---The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect.
      

  4.   

    Java的四舍五入我还没接触过...
      

  5.   

    同意一楼的说法
    改成
    System.out.println(new BigDecimal("0.01995").setScale(4,
                    RoundingMode.HALF_EVEN));
    就能得到0.0200
      

  6.   

    此群是一个 java Flex 技术群,如有想在知识方面想共同进步的请加入,长期不发言者 将会被清楚群号:90551956希望大家都能带着知识和问题进来
      

  7.   

    难怪,我还试过RoundingMode.HALF_UP, HALF_UP,如果位数超过4位都出现不准确的结果。
    领教了,但很难理解为什SUN要保留BigDicemal(Double value)这个可能产生不可预知结果的构造方法!
    谢谢各位,收贴了。
      

  8.   


    总结了一下:
    public class DoubleArith{
    // @2009-08-28
    // Description:
    // Double calculation        //default scale
    public static final int DEFAULT_SCALE = 10; // get Double instance
    public static Double getDouble(Double value) {
    if (!ObjectHelper.isNotNullAndNotEmpty(value)) {
    return new Double(0);
    }
    return value;
    } // get scale
    public static int getScale(int scale) {
    if (scale < 0) {
    return DEFAULT_SCALE;
    }
    return scale;
    } // round
    public static Double round(Double value, int scale) {
    scale = getScale(scale);
    BigDecimal b = new BigDecimal(Double.toString(value));
    BigDecimal one = new BigDecimal("1");
    return new Double(b.divide(one, scale, RoundingMode.HALF_EVEN)
    .doubleValue());
    } // ---------------------------------------------------------------------------------------------
    // Double calculation
    // --------------------------------------------------------------------------------------------- // 1. add
    public static Double add(Double value1, Double value2) {
    value1 = getDouble(value1);
    value2 = getDouble(value2);
    BigDecimal b1 = new BigDecimal(Double.toString(value1));
    BigDecimal b2 = new BigDecimal(Double.toString(value2));
    return new Double(b1.add(b2).doubleValue());
    } public static Double add(Double value1, Double value2, int scale) {
    Double value = add(value1, value2);
    return round(value, scale);
    } // 2. subtract
    public static Double sub(Double value1, Double value2) {
    value1 = getDouble(value1);
    value2 = getDouble(value2);
    BigDecimal b1 = new BigDecimal(Double.toString(value1));
    BigDecimal b2 = new BigDecimal(Double.toString(value2));
    return new Double(b1.subtract(b2).doubleValue());
    } public static Double sub(Double value1, Double value2, int scale) {
    Double value = sub(value1, value2);
    return round(value, scale);
    } // 3. multiply
    public static Double multiply(Double value1, Double value2) {
    value1 = getDouble(value1);
    value2 = getDouble(value2);
    BigDecimal b1 = new BigDecimal(Double.toString(value1));
    BigDecimal b2 = new BigDecimal(Double.toString(value2));
    return new Double(b1.multiply(b2).doubleValue());
    } public static Double multiply(Double value1, Double value2, int scale) {
    Double value = multiply(value1, value2);
    return round(value, scale);
    } // 4. divide
    public static Double divide(Double value1, Double value2) {
    value1 = getDouble(value1);
    value2 = getDouble(value2);
    BigDecimal b1 = new BigDecimal(Double.toString(value1));
    BigDecimal b2 = new BigDecimal(Double.toString(value2));
    try {
    return new Double(b1.divide(b2).doubleValue());
    } catch (ArithmeticException e) {
    return new Double(b1.divide(b2, -1, RoundingMode.HALF_EVEN)
    .doubleValue());
    }
    } public static Double divide(Double value1, Double value2, int scale) {
    Double value = divide(value1, value2);
    return round(value, scale);
    }}//end class