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 :-)

Agemen
  • 1,525
  • 9
  • 18

4 Answers4

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.

kale
  • 151
  • 1
  • 10
pasaba por aqui
  • 3,446
  • 16
  • 40
  • 1
    I tracked down the issue, just to find that you already did. You could also provide a [link to the source code](https://www.zgrepcode.com/java/oracle/jdk-8u181/java/text/decimalformat.java#L-614). 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… – Holger Dec 13 '18 at 16:39
  • @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. – pasaba por aqui Dec 13 '18 at 17:46
  • I agree that this is the OP’s main point. It’s just so easy to get misguided… – Holger Dec 14 '18 at 07:31
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));
Justin
  • 1,356
  • 2
  • 9
  • 16
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".

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
-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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Bsquare ℬℬ
  • 4,423
  • 11
  • 24
  • 44
  • I do no see direct relation between this answer and the subject of the original question – pasaba por aqui Dec 11 '18 at 14:46
  • 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`". – Bsquare ℬℬ Dec 11 '18 at 14:52
  • 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`. – rosshjb Dec 26 '21 at 07:32