Advertisement
Advertisement


How do I print a double value without scientific notation using Java?


Question

I want to print a double value in Java without exponential form.

double dexp = 12345678;
System.out.println("dexp: "+dexp);

It shows this E notation: 1.2345678E7.

I want it to print it like this: 12345678

What is the best way to prevent this?

2017/11/18
1
231
11/18/2017 12:37:36 PM

Accepted Answer

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

This uses the format specifier language explained in the documentation.

The default toString() format used in your original code is spelled out here.

2013/04/19
123
4/19/2013 5:51:56 AM


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_DIGITS

System.out.println(df.format(myValue)); // Output: 0.00000021

Explanation:

Why other answers did not suit me:

  • Double.toString() or System.out.println or FloatingDecimal.toJavaFormatString uses scientific notations if double is less than 10^-3 or greater than or equal to 10^7
  • By 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: 0
    DecimalFormat 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 of DecimalFormat.DOUBLE_FRACTION_DIGITS which equals 340
  • Double.MIN_VALUE = 4.9E-324 so with 340 digits you are sure not to round your double and lose precision.
2017/11/18

You can try it with DecimalFormat. With this class you are very flexible in parsing your numbers.
You can exactly set the pattern you want to use.
In your case for example:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
2013/04/19

I've got another solution involving BigDecimal's toPlainString(), but this time using the String-constructor, which is recommended in the javadoc:

this constructor is compatible with the values returned by Float.toString and Double.toString. This is generally the preferred way to convert a float or double into a BigDecimal, as it doesn't suffer from the unpredictability of the BigDecimal(double) constructor.

It looks like this in its shortest form:

return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();

Pre Java 8, this results in "0.0" for any zero-valued Doubles, so you would need to add:

if (myDouble.doubleValue() == 0)
    return "0";

NaN and infinite values have to be checked extra.

The final result of all these considerations:

public static String doubleToString(Double d) {
    if (d == null)
        return null;
    if (d.isNaN() || d.isInfinite())
        return d.toString();

    // Pre Java 8, a value of 0 would yield "0.0" below
    if (d.doubleValue() == 0)
        return "0";
    return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}

This can also be copied/pasted to work nicely with Float.

2017/11/18

This will work as long as your number is a whole number:

double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);

If the double variable has precision after the decimal point it will truncate it.

2014/01/05

Java/Kotlin compiler converts any value greater than 9999999 (greater than or equal to 10 million) to scientific notation ie. Epsilion notation.

Ex: 12345678 is converted to 1.2345678E7

Use this code to avoid automatic conversion to scientific notation:

fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your android text view using setText() function */
        salesTextView.setText( valueWithoutEpsilon.toPlainString() )
    }
2019/12/31