Format double values using a maximum of five total digits, rounding decimal digits if necessary

笑着哭i 提交于 2019-12-06 01:37:21

问题


I have double values which I would like to convert to String values with the following format restrictions:

number_of_fraction_digits = max( 0, 5 - number_of_integer_digits )

Essentially I want to keep the number of digits to 5 if possible, rounding decimal digits if necessary. For example:

 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

I've looked into using DecimalFormat but as far as I can tell it doesn't quite accomplish what I'm after.

It allows setting of the maximum number of decimal digits using setMaximumFractionDigits() but as far as I can tell I would have to calculate the number of integer digits and perform the above calculation myself.

So the basic question is whether there is a nice, clean built-in way to format numbers in this way.


回答1:


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:


eee's answer is much cleaner, and gets almost all the way there. However, I do have a strict requirement to have the number of digits (not including optional decimal point) always be less than a given number (say 5).

This includes any leading 0. for an entirely fractional number.

So:

Input: 0.111111 Output: 0.11111

is too long and needs to be:

Input: 0.111111 Output: 0.1111

This approach is much less elegant, but is more specific about guaranteeing the final length of the string.

I've posted it here for consideration since it may be the ultimate code that I go with to solve the problem even though it is less elegant.

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 ) );
    }
}


来源:https://stackoverflow.com/questions/9978205/format-double-values-using-a-maximum-of-five-total-digits-rounding-decimal-digi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!