Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of significant digits in scientific notation with DecimalFormat

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

like image 511
Agemen Avatar asked Dec 14 '11 13:12

Agemen


People also ask

What is number format and DecimalFormat class?

Class DecimalFormat. DecimalFormat is a concrete subclass of NumberFormat that formats decimal numbers. It has a variety of features designed to make it possible to parse and format numbers in any locale, including support for Western, Arabic, and Indic digits.

Is Java DecimalFormat thread safe?

DecimalFormat isn't thread-safe, thus we should pay special attention when sharing the same instance between threads.

What character is used in a format pattern to separate the integer part of a number from the fractional part?

Creating a DecimalFormat For a Specific Locale Notice the use of a comma instead of a dot to separate the integer part from the fraction part of the number.


1 Answers

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.

like image 169
pasaba por aqui Avatar answered Sep 25 '22 12:09

pasaba por aqui