Отформатируйте двойные значения, используя максимум пять общих цифр, округлив десятичные цифры, если это необходимо - PullRequest
6 голосов
/ 02 апреля 2012

У меня есть 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 ]

6 голосов
/ 02 апреля 2012
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));
        }
    }
}
2 голосов
/ 02 апреля 2012

Ответ 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 ) );
    }
}
...