Jak wydrukować podwójną wartość bez notacji naukowej przy użyciu Javy?

Chcę wydrukować podwójną wartość w Javie bez postaci wykładniczej.

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

Pokazuje ten zapis E: 1.2345678E7.

Chcę to wydrukować tak: 12345678

Jaki jest najlepszy sposób, aby temu zapobiec?

 166
Author: Peter Mortensen, 2013-04-19

12 answers

Możesz użyć printf() z %f:

double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);

To wydrukuje dexp: 12345678.000000. Jeśli nie chcesz części ułamkowej, użyj

System.out.printf("dexp: %.0f\n", dexp);

Używa języka określającego format wyjaśnionego w dokumentacji .

Domyślny format toString() użyty w oryginalnym kodzie jest napisany tutaj .

 88
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-19 05:51:56

Java prevent e notation in a double:

Pięć różnych sposobów konwersji liczby podwójnej na normalną:

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.println(new BigDecimal(myvalue).toPlainString());
        System.out.println();

        //Option 5, String.format 
        System.out.println(String.format("%.12f", myvalue));
    }
}

Ten program wyświetla:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Które mają tę samą wartość.

Protip: jeśli jesteś zdezorientowany, dlaczego te losowe cyfry pojawiają się poza pewnym progiem w podwójnej wartości, ten film wyjaśnia: computerphile dlaczego 0.1+0.2 równe 0.30000000000001?

Http://youtube.com/watch?v=PZRI1IfStY0

 196
Author: Eric Leschinski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-21 14:20:15

W skrócie:

Jeśli chcesz pozbyć się problemów z końcowymi zerami i Locale, powinieneś użyć:

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:

Dlaczego inne odpowiedzi mi nie odpowiadały:

  • Double.toString() lub System.out.println lub FloatingDecimal.toJavaFormatString używa notacji naukowych, jeśli podwójne jest mniejsze niż 10^-3 lub większe lub równe 10^7
  • Używając %f, domyślna dokładność dziesiętna wynosi 6, w przeciwnym razie można ją zakodować na twardo, ale powoduje to dodanie dodatkowych zer, jeśli mniej miejsc po przecinku. Przykład:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
    
  • Używając setMaximumFractionDigits(0); lub %.0f usuwasz dowolną precyzję dziesiętną, która jest dobra dla liczb całkowitych/długich, ale nie dla podwójnych:

    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
    
  • Używając DecimalFormat, jesteś zależny od miejsca. W języku francuskim separatorem dziesiętnym jest przecinek, a nie Punkt:

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue)); // Output: 0,00000021
    

    Używanie angielskich ustawień regionalnych daje pewność, że otrzymasz punkt dla separatora dziesiętnego, niezależnie od tego, gdzie program będzie uruchamiany.

Po co używać 340 wtedy dla setMaximumFractionDigits?

Dwa powody:

  • setMaximumFractionDigits akceptuje liczbę całkowitą, ale jej implementacja ma maksymalną dozwoloną liczbę cyfr DecimalFormat.DOUBLE_FRACTION_DIGITS, która wynosi 340
  • Double.MIN_VALUE = 4.9E-324 więc z 340 cyframi na pewno nie zaokrąglisz sobowtóra i stracisz precyzję.
 74
Author: JBE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-18 12:44:00

Możesz spróbować z DecimalFormat. Dzięki tej klasie jesteś bardzo elastyczny w analizowaniu swoich liczb.
Możesz dokładnie ustawić wzór, którego chcesz użyć.
W Twoim przypadku na przykład:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
 22
Author: Obl Tobl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-19 06:08:54

Mam inne rozwiązanie z Toplainstring () Bigdecimala, ale tym razem używając konstruktora Łańcuchowego, który jest zalecany w javadoc:

Ten konstruktor jest zgodny z wartościami zwracanymi przez Float.toString i Double.toString. Jest to na ogół preferowany sposób konwersji float lub double na BigDecimal, ponieważ nie cierpi on na nieprzewidywalność konstruktora BigDecimal (double).

Wygląda tak w najkrótszym forma:

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

Pre Java 8, daje to "0.0" dla dowolnych podwójnych wartości zerowych, więc trzeba by dodać:

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

Nan i wartości nieskończone muszą być dodatkowo sprawdzone.

Ostateczny wynik tych rozważań:

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

Można to również skopiować/wkleić, aby dobrze działało z Float.

 14
Author: Manuel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-18 12:50:51

To będzie działać tak długo, jak twoja liczba jest liczbą całkowitą:

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

Jeśli Podwójna zmienna ma dokładność po przecinku, to ją obetnie.

 8
Author: NateS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-05 18:43:49

Musiałem przeliczyć kilka podwójnych wartości na waluty i stwierdziłem, że większość rozwiązań była OK, ale nie dla mnie.

DecimalFormat w końcu była dla mnie drogą, więc oto co zrobiłem:

   public String foo(double value) //Got here 6.743240136E7 or something..
    {
        DecimalFormat formatter;

        if(value - (int)value > 0.0)
            formatter = new DecimalFormat("0.00"); // Here you can also deal with rounding if you wish..
        else
            formatter = new DecimalFormat("0");

        return formatter.format(value);
    }

Jak widać, jeśli liczba jest naturalna dostaję - powiedzmy-20000000 zamiast 2E7 (itd.)- bez kropki dziesiętnej.

I jeśli jest dziesiętny, dostaję tylko dwie cyfry dziesiętne.

 4
Author: JamesC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-18 12:52:26

Poniższy kod wykrywa, czy podana liczba jest przedstawiona w notacji naukowej. Jeśli tak, to jest reprezentowany w normalnej Prezentacji z maksymalnie " 25 " cyfr.

 static String convertFromScientificNotation(double number) {
    // Check if in scientific notation
    if (String.valueOf(number).toLowerCase().contains("e")) {
        System.out.println("The scientific notation number'"
                + number
                + "' detected, it will be converted to normal representation with 25 maximum fraction digits.");
        NumberFormat formatter = new DecimalFormat();
        formatter.setMaximumFractionDigits(25);
        return formatter.format(number);
    } else
        return String.valueOf(number);
}
 3
Author: Memin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-08 00:37:21

Miałem ten sam problem w moim kodzie produkcyjnym, kiedy używałem go jako string input do matematyki.Funkcja Eval () przyjmująca ciąg znaków jak "x + 20 / 50"

Przejrzałem setki artykułów... W końcu poszedłem z tym ze względu na szybkość. A ponieważ funkcja Eval miała zamiar przekonwertować go z powrotem do własnego formatu liczbowego w końcu i matematyki.Eval() nie wspierała trailingu E-07, który zwróciły inne metody, a wszystko powyżej 5 dp było zbyt szczegółowe dla mojej aplikacji w każdym razie.

Jest to obecnie używane w kodzie produkcyjnym dla aplikacji, która ma ponad 1000 użytkowników...

double value = 0.0002111d;
String s = Double.toString(((int)(value * 100000.0d))/100000.0d); // Round to 5 dp

s display as:  0.00021
 1
Author: hamish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-18 12:49:24

Kompilator Java/Kotlin konwertuje dowolną wartość większą niż 9999999 (większą lub równą 10 milionom) na notację naukową, tj. Notacja Epsilion.

Ex: 12345678 jest zamienione na 1. 2345678E7

Użyj tego kodu, aby uniknąć automatycznej konwersji na notację naukową:

fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your android view using setText() function */
        totalSalesValue.setText() = valueWithoutEpsilon.toPlainString()
    }
 1
Author: Ramakrishna Joshi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 05:51:02

Myślę, że każdy miał dobry pomysł, ale wszystkie odpowiedzi nie były proste. Widzę, że jest to bardzo przydatny fragment kodu. Oto fragment tego, co będzie działać:

System.out.println(String.format("%.8f", EnterYourDoubleVariableHere));

{[1] } to miejsce, w którym ustawiasz liczbę miejsc po przecinku, które chcesz pokazać.

Używam Eclipse i działało bez problemu.

Mam nadzieję, że to było pomocne. Będę wdzięczny za wszelkie opinie!
 0
Author: Brian Castro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 01:58:56

Dla wartości całkowitych reprezentowanych przez double, można użyć tego kodu, który jest znacznie szybszy niż inne rozwiązania.

public static String doubleToString(final double d) {
    // check for integer, also see https://stackoverflow.com/a/9898613/868941 and
    // https://github.com/google/guava/blob/master/guava/src/com/google/common/math/DoubleMath.java
    if (isMathematicalInteger(d)) {
        return Long.toString((long)d);
    } else {
        // or use any of the solutions provided by others
        return Double.toString(d);
    }
}

// Java 8+
public static boolean isMathematicalInteger(final double d) {
    return StrictMath.rint(d) == d && Double.isFinite(d);
}
 0
Author: rmuller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-18 07:33:31