Number of significant digits in scientific notation with DecimalFormat
Asked Answered
P

4

16

I'm trying to understand fully the exact behaviour of DecimalFormat. I'm currently making some tests with the scientific notation capabilities of this class. And I'm facing a problem with the tuning of the exact number of significant digits in scientific notation. According to the Javadoc of Java 7 :

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.

Consequently, I'm testing it :

DecimalFormat formatone = new DecimalFormat("##0.##E0");
System.out.println(formatone.format(toF));

And I obtain the following output :

12,345E3

According to the excerpt of the Javadoc I've just shown, I thought I should obtain

12.3E3

Am I doing something wrong ? Have I understood something wrong ?

Thanks in advance for all your clarifications :-)

Pansypant answered 14/12, 2011 at 13:57 Comment(2)
Which Java version do you use?Audriaaudrie
Did you see/check my answer?Audriaaudrie
E
7

I've printed the values for the minimum/maximum integer/fraction digits in the case "##0.##E0" and verified the results given by @Agemen:

DecimalFormat df = new DecimalFormat( "##0.##E0" );
System.out.printf("getMinimumIntegerDigits=%d\n", df.getMinimumIntegerDigits() );
System.out.printf("getMaximumIntegerDigits=%d\n", df.getMaximumIntegerDigits() );
System.out.printf("getMinimumFractionDigits=%d\n", df.getMinimumFractionDigits() );
System.out.printf("getMaximumFractionDigits=%d\n", df.getMaximumFractionDigits() );

double v = 12345;
System.out.printf("s=%f\n", v );
System.out.printf("r=%s\n", df.format(v) );

with the result:

getMinimumIntegerDigits=1
getMaximumIntegerDigits=3
getMinimumFractionDigits=0
getMaximumFractionDigits=2
s=12345.000000
r=12.345E3

In my opinion, this is an error in Java implementation or in documentation, the expected result is not obtained.

About the example given in the @JoopEggen answer, it is not applicable, because pattern "##0.#####E0" has a maximum number of fraction digits equal to 5.

In fact, the expected string is obtained using the pattern "##0.E0".

The error is probably in file DecimalFormat.java, at statement:

digitList.set(isNegative, number,
useExponentialNotation ? 
maxIntDigits + maxFraDigits : maxFraDigits,
!useExponentialNotation);

Where addition "maxIntDigits + maxFraDigits" should be "minIntDigits + maxFraDigits" to agree with the java documentation.

Exon answered 8/12, 2018 at 22:22 Comment(3)
I tracked down the issue, just to find that you already did. You could also provide a link to the source code. Note that there are two issues, which is the reason why the other answers did not address your issue. The documentation is also sloppy about the locale dependency, so the OP used a non-US locale where the separators do not match the documentation. Since the question did not emphasizes the mismatch of the significant digits, the other answers focused on the separators rather than significant digits…Monolith
@Holger: thanks for your comment. I've not perceived the difference in the symbol, I've found this question/answer after see an unexpected number of decinals in one of my programs. This is, in my opinion, the main point and the one (?) the OP refers.Exon
I agree that this is the OP’s main point. It’s just so easy to get misguided…Monolith
L
1

You ignore the part that says the mantissa is the sum of the minimum integer and maximum fraction digits

To get your desired output, you need to set those values:

    DecimalFormat formatone = new DecimalFormat("##0.##E0");
    formatone.setMinimumIntegerDigits(2);
    formatone.setMaximumFractionDigits(0);
    System.out.println(formatone.format(12345));
Lampyrid answered 14/12, 2018 at 0:44 Comment(0)
H
0

From http://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html stems the following "explanation." One wonders.

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, e.g., "##0.#####E0". Using this pattern, the number 12345 formats to "12.345E3", and 123456 formats to "123.456E3".

Hypermetropia answered 14/12, 2011 at 14:12 Comment(0)
M
-1

Be sure to control the decimal AND the grouping separators when you format decimals.

This is a way to do it (note all the format pattern alternatives):

@Test
public void test() {        
    double toF = 12345;
    DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols();
    decimalFormatSymbols.setDecimalSeparator('.');
    decimalFormatSymbols.setGroupingSeparator(',');

    System.out.println((new DecimalFormat("#.#E0", decimalFormatSymbols)).format(toF));
    System.out.println((new DecimalFormat("#0.#E0", decimalFormatSymbols)).format(toF));
    System.out.println((new DecimalFormat("##0.#E0", decimalFormatSymbols)).format(toF));
    System.out.println((new DecimalFormat("##0.##E0", decimalFormatSymbols)).format(toF));
    System.out.println((new DecimalFormat("##0.###E0", decimalFormatSymbols)).format(toF));
}

It outputs:

1.2E4
1.23E4
12.34E3
12.345E3
12.345E3

You can get further information in the Java 8 API Documentation, which may be newer than the one you were looking at so far.

Methadone answered 11/12, 2018 at 14:16 Comment(3)
I do no see direct relation between this answer and the subject of the original questionExon
Read again what said OP: "And I obtain the following output 12,345E3"; "according to the excerpt of the Javadoc I've just shown, I thought I should obtain 12.3E3".Audriaaudrie
You didn't answer the question. The OP said that why the output is 12.345E3(the comma in original question seems to be typo), not 12.3E3.Malapropos

© 2022 - 2024 — McMap. All rights reserved.