如何将一个double加到n个长度(不是n个小数位)?

时间:2016-12-04 23:19:44

标签: java double rounding

我一直试图找到一种方法来确保双“值”的长度不大于10.然而,这变得很难编程,因为我没有将它四舍五入到一定数量的小数位。

例如,1234567.8912和12.345678912都大于10位数,但是,它们必须四舍五入到不同的小数位数。我的逻辑是找到小数点出现的位置并将双精度舍入为“10 - 小数位前的位数”。

我创建了两种不同的方法,这两种方法似乎都无法正常工作。

    if ((Double.toString(value)).length()> 10){
        int counter = 0;
        double no_of_dec = 1;
        double no_of_int = 1;
        double new_value = 0;
        for (int i = 0; i< (Double.toString(value)).length(); i++){
            if ( (Character.toString((Double.toString(value)).charAt(i))).equals(".") ){
                counter = 1;
            } if (counter == 1){
                no_of_dec = no_of_dec * 10;
            } else if (counter == 0){
                no_of_int = no_of_int * 10;
            }
        } 
        no_of_dec = no_of_dec / (no_of_int);
        new_value = (double)Math.round(value * 100d/100d);
        return Double.toString(new_value);
    } else {
        return Double.toString(value);
    }


    if ((Double.toString(value)).length()> 10){
        double no_of_dec = 0;
        double no_of_int = 0;
        double new_value = 0;
        for (int i = 0; i< (Double.toString(value)).length(); i++){
            while (!(Character.toString((Double.toString(value)).charAt(i))).equals(".")){
                no_of_int = no_of_int + 1;
            }
        }
        no_of_dec = (Double.toString(value)).length() - no_of_int;
        no_of_dec = no_of_dec * 10;
        new_value = (double)Math.round(value * no_of_dec/no_of_dec);
        return Double.toString(new_value);
    } else {
        return Double.toString(value);
    }
}

2 个答案:

答案 0 :(得分:3)

我是这样做的:

private static BigDecimal getRounded(double n, int totalDigits) {

    String nString = Double.toString(n); // transform to string to make the job easier

    if(nString.contains(".")) {
        int dotPos = nString.indexOf("."); // = number of digits before the decimal point

        int remainingDigits = totalDigits - dotPos; // = remaining digits after the decimal point

        return new BigDecimal(nString).setScale(remainingDigits, BigDecimal.ROUND_HALF_UP); // round
    }

    return new BigDecimal(n);
}

这是我的测试:

double n = 1234567.8912;
System.out.println(getRounded(n, 10));

n = 12.345678915;
System.out.println(getRounded(n, 10));

这就是结果:

1234567.891
12.34567892

演示:http://ideone.com/my7eB2

答案 1 :(得分:0)

BigDecimal执行此操作:

double truncate(double value) {
    BigDecimal b = new BigDecimal(String.valueOf(value));
    b = b.round(new MathContext(10));
    return b.doubleValue();
}

使用BigDecimal(String)构造函数而不是BigDecimal(double)构造函数是有原因的。双打和浮点数不是基数10,因此它们并不完全代表我们打印时看到的值; constructor documentation很好地说明了这一点。这不是Java独有的,在大多数语言中也是如此。

<强>更新

4castle指出上述内容不适用于幅度小于1的非零数字,因为BigDecimal不会将零整数部分视为有效数字。你可以解决这个问题:

double truncate(double value) {
    int precision = 10;
    if (value != 0 && Math.abs(value) < 1) {
        precision--;
    }

    BigDecimal b = new BigDecimal(String.valueOf(value));
    b = b.round(new MathContext(precision));
    return b.doubleValue();
}

更新2:

BackSlash指出,对于介于-1和1之间的非零数字,它比上述更复杂。我确信可以计算所需的精确精度,但我认为通过添加1进行舍入来消除问题更简单用途:

double truncate(double value) {
    BigDecimal b = new BigDecimal(String.valueOf(value));

    MathContext context = new MathContext(10);
    if (value > 0 && value < 1) {
        b = b.add(BigDecimal.ONE);
        b = b.round(context);
        b = b.subtract(BigDecimal.ONE);
    } else if (value < 0 && value > -1) {
        b = b.subtract(BigDecimal.ONE);
        b = b.round(context);
        b = b.add(BigDecimal.ONE);
    } else {
        b = b.round(context);
    }

    return b.doubleValue();
}