How do I print a double value without scientific notation using Java?
Java prevent E notation in a double:
Five different ways to convert a double to a normal number:
import java.math.BigDecimal;import java.text.DecimalFormat;public class Runner { public static void main(String[] args) { double myvalue = 0.00000021d; //Option 1 Print bare double. System.out.println(myvalue); //Option2, use decimalFormat. DecimalFormat df = new DecimalFormat("#"); df.setMaximumFractionDigits(8); System.out.println(df.format(myvalue)); //Option 3, use printf. System.out.printf("%.9f", myvalue); System.out.println(); //Option 4, convert toBigDecimal and ask for toPlainString(). System.out.print(new BigDecimal(myvalue).toPlainString()); System.out.println(); //Option 5, String.format System.out.println(String.format("%.12f", myvalue)); }}
This program prints:
2.1E-7.000000210.0000002100.0000002100000000000000010850153241148685623329583904705941677093505850.000000210000
Which are all the same value.
Protip: If you are confused as to why those random digits appear beyond a certain threshold in the double value, this video explains: computerphile why does 0.1
+0.2
equal 0.30000000000001
?
You could use printf()
with %f
:
double dexp = 12345678;System.out.printf("dexp: %f\n", dexp);
This will print dexp: 12345678.000000
. If you don't want the fractional part, use
System.out.printf("dexp: %.0f\n", dexp);
0 in %.0f
means 0 places in fractional part i.e no fractional part. If you want to print fractional part with desired number of decimal places then instead of 0 just provide the number like this %.8f
. By default fractional part is printed up to 6 decimal places.
This uses the format specifier language explained in the documentation.
The default toString()
format used in your original code is spelled out here.
In short:
If you want to get rid of trailing zeros and Locale problems, then you should use:
double myValue = 0.00000021d;DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITSSystem.out.println(df.format(myValue)); // Output: 0.00000021
Explanation:
Why other answers did not suit me:
Double.toString()
orSystem.out.println
orFloatingDecimal.toJavaFormatString
uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7By using
%f
, the default decimal precision is 6, otherwise you can hardcode it, but it results in extra zeros added if you have fewer decimals. Example:double myValue = 0.00000021d;String.format("%.12f", myvalue); // Output: 0.000000210000
By using
setMaximumFractionDigits(0);
or%.0f
you remove any decimal precision, which is fine for integers/longs, but not for double:double myValue = 0.00000021d;System.out.println(String.format("%.0f", myvalue)); // Output: 0DecimalFormat df = new DecimalFormat("0");System.out.println(df.format(myValue)); // Output: 0
By using DecimalFormat, you are local dependent. In French locale, the decimal separator is a comma, not a point:
double myValue = 0.00000021d;DecimalFormat df = new DecimalFormat("0");df.setMaximumFractionDigits(340);System.out.println(df.format(myvalue)); // Output: 0,00000021
Using the ENGLISH locale makes sure you get a point for decimal separator, wherever your program will run.
Why using 340 then for setMaximumFractionDigits
?
Two reasons:
setMaximumFractionDigits
accepts an integer, but its implementation has a maximum digits allowed ofDecimalFormat.DOUBLE_FRACTION_DIGITS
which equals 340Double.MIN_VALUE = 4.9E-324
so with 340 digits you are sure not to round your double and lose precision.