wake-up-neo.com

Wie drucke ich einen doppelten Wert ohne wissenschaftliche Notation mit Java?

Ich möchte einen doppelten Wert in Java ohne Exponentialform drucken.

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

Es zeigt diese E-Notation: 1.2345678E7.

Ich möchte, dass es so gedruckt wird: 12345678

Wie kann man dies am besten verhindern?

181
Despicable

Sie könnten printf() mit %f verwenden:

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

Dies wird dexp: 12345678.000000 drucken. Wenn Sie den Bruchteil nicht möchten, verwenden Sie

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

Hierbei wird die Formatbezeichnersprache verwendet, die in der Dokumentation documentation erläutert wird.

Das in Ihrem Originalcode verwendete Standardformat toString() ist hier angegeben.

95
NPE

Java verhindert die E-Notation in einem Double:

Fünf verschiedene Möglichkeiten, ein Double in eine normale Zahl umzuwandeln:

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

Dieses Programm druckt:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Welches sind alle der gleiche Wert.

Protip: Wenn Sie verwirrt sind, warum diese zufälligen Ziffern einen bestimmten Schwellenwert im Doppelwert überschreiten, wird in diesem Video erläutert: computerphile, warum 0.1 + 0.2 gleich 0.30000000000001 ist

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

212
Eric Leschinski

Zusamenfassend:

Wenn Sie nachfolgende Nullen und Gebietsschemaprobleme beseitigen möchten, sollten Sie Folgendes verwenden:

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

Erklärung:

Warum andere Antworten nicht zu mir passten:

  • Double.toString() oder System.out.println oder FloatingDecimal.toJavaFormatString verwendet wissenschaftliche Notationen, wenn double kleiner als 10 ^ -3 oder größer als oder gleich 10 ^ 7 ist
  • Wenn Sie %f verwenden, ist die Standard-Dezimalgenauigkeit 6, ansonsten können Sie sie hartcodieren. Bei weniger Dezimalzahlen werden jedoch zusätzliche Nullen hinzugefügt. Beispiel:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
    
  • Mit setMaximumFractionDigits(0); oder %.0f entfernen Sie jede Dezimalgenauigkeit, die für Ganzzahlen/Longs geeignet ist, nicht jedoch für 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
    
  • Durch die Verwendung von DecimalFormat sind Sie lokal abhängig. Im französischen Gebietsschema ist das Dezimaltrennzeichen ein Komma und kein Punkt:

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

    Die Verwendung des Gebietsschemas ENGLISH stellt sicher, dass Sie einen Punkt für das Dezimaltrennzeichen erhalten, wo auch immer Ihr Programm ausgeführt wird.

Warum dann 340 für setMaximumFractionDigits verwenden?

Zwei Gründe:

  • setMaximumFractionDigits akzeptiert eine ganze Zahl, aber für ihre Implementierung sind maximal zulässige Ziffern von DecimalFormat.DOUBLE_FRACTION_DIGITS zulässig, was 340 entspricht
  • Double.MIN_VALUE = 4.9E-324 Mit 340 Ziffern runden Sie also sicher nicht ab und verlieren an Präzision.
77
JBE

Sie können es mit DecimalFormat versuchen. Mit dieser Klasse können Sie Ihre Zahlen sehr flexibel analysieren.
Sie können das gewünschte Muster genau einstellen.
In Ihrem Fall zum Beispiel:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678
25
Obl Tobl

Ich habe eine andere Lösung mit toPlainString () von BigDecimal, aber diesmal unter Verwendung des String-Konstruktors, der im Javadoc empfohlen wird:

dieser Konstruktor ist mit den von Float.toString und Double.toString zurückgegebenen Werten kompatibel. Dies ist im Allgemeinen die bevorzugte Methode, um einen Float oder einen Double in einen BigDecimal-Wert zu konvertieren, da er nicht unter der Unvorhersehbarkeit des BigDecimal-Konstruktors (Double) leidet.

Es sieht in seiner kürzesten Form so aus:

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

Vor Java 8 führt dies zu "0,0" für Doubles mit Nullwert. Sie müssen also Folgendes hinzufügen:

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

NaN und unendliche Werte müssen extra geprüft werden.

Das Endergebnis all dieser Überlegungen:

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

Dies kann auch kopiert/eingefügt werden, um mit Float gut zu funktionieren.

14
Manuel

Dies funktioniert solange Ihre Nummer eine ganze Zahl ist:

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

Wenn die Doppelvariable eine Genauigkeit nach dem Dezimalpunkt hat, wird sie gekürzt.

8
NateS

Ich musste einige doppelte in Währungswerte umwandeln und stellte fest, dass die meisten Lösungen in Ordnung waren, aber nicht für mich.

Die DecimalFormat war schließlich der Weg für mich, also habe ich Folgendes getan:

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

Wie Sie sehen, bekomme ich - wenn die Zahl natürlich ist - 20000000 anstelle von 2E7 (usw.) - ohne Dezimalpunkt.

Und wenn es dezimal ist, bekomme ich nur zwei Dezimalstellen.

4
JamesC

Java/Kotlin-Compiler konvertiert jeden Wert, der größer als 9999999 (größer oder gleich 10 Millionen) ist, in wissenschaftliche Notation, d. Epsilion-Notation 

Bsp: 12345678 wird in 1,2345678E7 konvertiert

Verwenden Sie diesen Code, um die automatische Konvertierung in wissenschaftliche Notation zu vermeiden:

fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your Android view using setText() function */
        totalSalesValue.setText() = valueWithoutEpsilon.toPlainString()
    }
3

Der folgende Code erkennt, ob die angegebene Nummer in wissenschaftlicher Notation angegeben ist. Wenn ja, wird es in normaler Darstellung mit maximal 25 Stellen dargestellt.

 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
Memin

Ich hatte das gleiche Problem in meinem Produktionscode, als ich es als Zeichenfolgeingabe für eine math.Eval () - Funktion verwendete, die eine Zeichenfolge wie "x + 20/50" annimmt.

Ich habe mir hunderte Artikel angesehen ... Am Ende bin ich wegen der Geschwindigkeit damit einverstanden. Und weil die Eval-Funktion sie letztendlich wieder in ihr eigenes Zahlenformat umwandeln würde und math.Eval () die nachfolgende E-07 nicht unterstützte, die von anderen Methoden zurückgegeben wurde, und alles, was über 5 dp lag, war ohnehin zu viel Detail für meine Anwendung .

Dies wird jetzt im Produktionscode für eine Anwendung mit mehr als 1.000 Benutzern verwendet.

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

s display as:  0.00021
1
hamish

Für ganzzahlige Werte, die durch eine double dargestellt werden, können Sie diesen Code verwenden, der viel schneller ist als die anderen Lösungen.

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
rmuller

Ich denke, jeder hatte die richtige Idee, aber alle Antworten waren nicht eindeutig. Ich kann sehen, dass dies ein sehr nützlicher Code ist. Hier ist ein Ausschnitt davon, was funktionieren wird:

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

im ".8" legen Sie die Anzahl der Dezimalstellen fest, die Sie anzeigen möchten.

Ich benutze Eclipse und es hat kein Problem geklappt.

Hoffe das war hilfreich. Ich würde mich über Feedback freuen!

0
Brian Castro

Meine Lösung: String str = String.format ("% .0f", yourDouble);

0