使用最多五位总数格式化双精度值,必要时舍入十进制数字

时间:2012-04-02 14:24:38

标签: java number-formatting

我有double个值,我希望将其转换为String值,并采用以下格式限制:

  

number_of_fraction_digits = max(0,5-number_of_integer_digits)

基本上我想在可能的情况下将位数保持为5,必要时舍入十进制数字。例如:

 float          String
-------------------------
     1               1
   100             100
100000          100000
 99999           99999
 99999.99        99999
  9999.99         9999.9
   999.99          999.99
    23.34324        23.343

我已经研究过使用DecimalFormat,但据我所知,它并没有完全实现我所追求的目标。

它允许使用setMaximumFractionDigits()设置最大小数位数,但据我所知,我必须计算整数位数并自行执行上述计算。

所以基本的问题是,是否有一种漂亮,干净的内置方式来以这种方式格式化数字。

2 个答案:

答案 0 :(得分:6)

public class SignificantFormat {

    public static String formatSignificant(double value, int significant)
    {
        MathContext mathContext = new MathContext(significant, RoundingMode.DOWN);
        BigDecimal bigDecimal = new BigDecimal(value, mathContext);
        return bigDecimal.toPlainString();
    }

    public static void main(String[] args) {
        double[] data = { 1, 100, 100000, 99999, 99999.99, 9999.99, 999.99, 23.34324 };
        for(double d: data){
            System.out.printf("Input: %10s \tOutput: %10s\n", Double.toString(d), formatSignificant(d, 5));
        }
    }
}

答案 1 :(得分:2)

eee的答案更清晰,几乎可以在那里完成任务。但是,我确实要求数字位数(不包括可选小数点)始终小于给定数字(例如5)。

这包括任何前导0.的完整小数。

所以:

Input: 0.111111 Output: 0.11111

太长了,需要:

Input: 0.111111 Output: 0.1111

这种方法不那么优雅,但更具体地说是保证字符串的最终长度。

我已将它发布在此处供考虑,因为它可能是解决问题的最终代码,即使它不太优雅。

public static String format( double value, int totalDigits )
{
    String s = String.valueOf( value );
    int decimal = s.indexOf( '.' );

    // there is no decimal part, so simply return the String
    if ( decimal == -1 )
    {
        return s;
    }
    else
    {
        int finalLength;

        // example: 23.34324
        // the final result will be length totalDigits + 1 because we will include the decimal
        if ( decimal < totalDigits )
        {
            finalLength = totalDigits + 1;
        }
        // example: 99999
        // the final result will be length totalDigits because there will be no decimal
        else if ( decimal == totalDigits )
        {
            finalLength = totalDigits;
        }
        // example: 999999.999
        // we can't make the final length totalDigits because the integer portion is too large
        else
        {
            finalLength = decimal;
        }

        finalLength = Math.min( s.length( ), finalLength );

        return s.substring( 0, finalLength );
    }
}

public static void main( String[] args )
{
    double[] data = { 1, 100, 1000, 10000, 100000, 99999, 99999.99, 9999.99, 999.99, 23.34324, 0.111111 };
    for ( double d : data )
    {
        System.out.printf( "Input: %10s \tOutput: %10s\n", Double.toString( d ), format( d, 5 ) );
    }
}