简体   繁体   中英

Format double in engineering notation with fixed number of fractional digits

I want to use a DecimalFormat that formats numbers in engineering notation (exponent is a multiple of 3) and with a fixed number of fractional digits. The number of fractional digits should be configurable by the pattern.

Is that possible with the java.text.DecimalFormat class. Is there an alternative?

Here is the test case that outputs 12.345E3 instead of 12.34E3:

public static void main(String[] args)
{
    Locale.setDefault(Locale.ENGLISH);
    DecimalFormat df = new DecimalFormat("##0.00E0");

    String realOutput = df.format(12345);
    String expected = "12.34E3";

    System.out.println(realOutput);
    if (Objects.equals(realOutput, expected))
    {
        System.out.println("OK");
    }
    else
    {
        System.err.println("Formatted output " + realOutput + " differs from documented output " + expected);
    }
}

You should use following:

DecimalFormat format = new DecimalFormat("##0.0E0");

Here http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html

You may find out answer on your question in part of "Science Notation"

Numbers in scientific notation are expressed as the product of a mantissa and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The mantissa is often in the range 1.0 <= x < 10.0, but it need not be. DecimalFormat can be instructed to format and parse scientific notation only via a pattern; there is currently no factory method that creates a scientific notation format. In a pattern, the exponent character immediately followed by one or more digit characters indicates scientific notation. Example: "0.###E0" formats the number 1234 as "1.234E3".

The number of digit characters after the exponent character gives the minimum exponent digit count. There is no maximum. Negative exponents are formatted using the localized minus sign, not the prefix and suffix from the pattern. This allows patterns such as "0.###E0 m/s". The minimum and maximum number of integer digits are interpreted together: If the maximum number of integer digits is greater than their minimum number and greater than 1, it forces the exponent to be a multiple of the maximum number of integer digits, and the minimum number of integer digits to be interpreted as 1. The most common use of this is to generate engineering notation, in which the exponent is a multiple of three, eg, "##0.#####E0". Using this pattern, the number 12345 formats to "12.345E3", and 123456 formats to "123.456E3". Otherwise, the minimum number of integer digits is achieved by adjusting the exponent. Example: 0.00123 formatted with "00.###E0" yields "12.3E-4". The number of significant digits in the mantissa is the sum of the minimum integer and maximum fraction digits, and is unaffected by the maximum integer digits. For example, 12345 formatted with "##0.##E0" is "12.3E3". To show all digits, set the significant digits count to zero. The number of significant digits does not affect parsing. Exponential patterns may not contain grouping separators.

taken from this website :

private final static int PREFIX_OFFSET = 5;
private final static String[] PREFIX_ARRAY = {"f", "p", "n", "µ", "m", "", "k", "M", "G", "T"};

public static String convert(double val, int dp)
{
   // If the value is zero, then simply return 0 with the correct number of dp
   if (val == 0) return String.format("%." + dp + "f", 0.0);

   // If the value is negative, make it positive so the log10 works
   double posVal = (val<0) ? -val : val;
   double log10 = Math.log10(posVal);

   // Determine how many orders of 3 magnitudes the value is
   int count = (int) Math.floor(log10/3);

   // Calculate the index of the prefix symbol
   int index = count + PREFIX_OFFSET;

   // Scale the value into the range 1<=val<1000
   val /= Math.pow(10, count * 3);

   if (index >= 0 && index < PREFIX_ARRAY.length)
   {
      // If a prefix exists use it to create the correct string
      return String.format("%." + dp + "f%s", val, PREFIX_ARRAY[index]);
   }
   else
   {
      // If no prefix exists just make a string of the form 000e000
      return String.format("%." + dp + "fe%d", val, count * 3);
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM