Frage

Ich habe einen Doppelwert = 1.068879335 Ich möchte es mit nur zwei Dezimalwerten wie 1,07 umrunden.

Ich habe es so versucht

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value);
double finalValue = Double.parseDouble(formate) ;

Dies gibt mir diese folgende Ausnahme

java.lang.NumberFormatException: For input string: "1,07"
     at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
     at java.lang.Double.parseDouble(Double.java:510)

Kann mir jemand sagen, was mit meinem Code los ist?

endgültig ich brauche das FinalValue = 1.07;

War es hilfreich?

Lösung

Beachten Sie das Komma in Ihrer Zeichenfolge: "1,07". DecimalFormat verwendet eine lokalspezifische Separatorzeichenfolge, während Double.parseDouble() nicht. Wenn Sie zufällig in einem Land leben, in dem das Dezimalseparator "" ist ", können Sie Ihre Nummer nicht zurück analysieren.

Sie können jedoch dasselbe verwenden DecimalFormat Um es zurückzuschätzen:

DecimalFormat df=new DecimalFormat("0.00");
String formate = df.format(value); 
double finalValue = (Double)df.parse(formate) ;

Aber Sie sollten dies stattdessen wirklich tun:

double finalValue = Math.round( value * 100.0 ) / 100.0;

Notiz: Wie ausgedrückt, sollten Sie nur einen schwimmenden Punkt verwenden, wenn Sie keine genaue Kontrolle über die Genauigkeit benötigen. (Finanzberechnungen sind das Hauptbeispiel für wann nicht sie benutzen.)

Andere Tipps

Live @Sergeys Lösung, aber mit ganzzahliger Division.

double value = 23.8764367843;
double rounded = (double) Math.round(value * 100) / 100;
System.out.println(value +" rounded is "+ rounded);

Drucke

23.8764367843 rounded is 23.88

Bearbeiten: Wie Sergey betont, sollte es keinen Unterschied zwischen dem Multiplieren von Double*int und doppelt*doppelt und doppelt/int und doppelt/doppelt geben. Ich kann kein Beispiel finden, in dem das Ergebnis unterschiedlich ist. Auf x86/x64 und anderen Systemen gibt es jedoch einen bestimmten Maschinencode -Befehl für gemischte Doppelwerte, von denen ich glaube, dass sie das JVM verwendet.

for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100) / 100;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,int operations %,d%n", time);
}
for (int j = 0; j < 11; j++) {
    long start = System.nanoTime();
    for (double i = 1; i < 1e6; i *= 1.0000001) {
        double rounded = (double) Math.round(i * 100.0) / 100.0;
    }
    long time = System.nanoTime() - start;
    System.out.printf("double,double operations %,d%n", time);
}

Drucke

double,int operations 613,552,212
double,int operations 661,823,569
double,int operations 659,398,960
double,int operations 659,343,506
double,int operations 653,851,816
double,int operations 645,317,212
double,int operations 647,765,219
double,int operations 655,101,137
double,int operations 657,407,715
double,int operations 654,858,858
double,int operations 648,702,279
double,double operations 1,178,561,102
double,double operations 1,187,694,386
double,double operations 1,184,338,024
double,double operations 1,178,556,353
double,double operations 1,176,622,937
double,double operations 1,169,324,313
double,double operations 1,173,162,162
double,double operations 1,169,027,348
double,double operations 1,175,080,353
double,double operations 1,182,830,988
double,double operations 1,185,028,544

Das Problem ist, dass Sie in Ihrem Fall ein lokalisiertes Formatierer verwenden, das in Ihrem Fall "lokalspezifische Dezimalpunkte" generiert. Aber double.Parsedouble () erwartet nicht lokalisierte Doppelwörtel. Sie können Ihr Problem lösen, indem Sie eine lokalspezifische Parsen-Methode verwenden oder das Gebietsschema Ihres Formaters in etwas ändern, das "verwendet". als Dezimalpunkt. Oder noch besser, vermeiden Sie unnötige Formatierung, indem Sie so etwas verwenden:

double rounded = (double) Math.round(value * 100.0) / 100.0;

Es ist etwas grundlegend falsch mit dem, was Sie versuchen zu tun. Binär-Gleitkommawerte nicht haben Nachkommastellen. Sie können eins nicht sinnvoll auf eine bestimmte Anzahl von Dezimalstellen runden, da die meisten "runden" Dezimalwerte einfach nicht als binäre Bruchteil dargestellt werden können. Deshalb sollte man niemals verwenden float oder double Geld darstellen.

Wenn Sie also Dezimalstellen in Ihrem Ergebnis wünschen, muss dieses Ergebnis entweder a sein String (was Sie bereits mit dem bekommen haben DecimalFormat), oder ein BigDecimal (das hat a setScale() Methode, die genau das tut, was Sie wollen). Andernfalls kann das Ergebnis nicht das sein, was Sie wollen.

Lesen Die Gleitkommahandbuch für mehr Informationen.

Versuchen Sie dies: org.apache.commons.math3.util.precision.round (Double X, Int Scale)

Sehen:http://commons.apache.org/proper/commons-math/apidocs/org/apache/commons/math3/util/precision.html

Apache Commons Mathematics Library Homepage lautet:http://commons.apache.org/proper/commons-math/index.html

Die interne Implemetation dieser Methode ist:

public static double round(double x, int scale) {
    return round(x, scale, BigDecimal.ROUND_HALF_UP);
}

public static double round(double x, int scale, int roundingMethod) {
    try {
        return (new BigDecimal
               (Double.toString(x))
               .setScale(scale, roundingMethod))
               .doubleValue();
    } catch (NumberFormatException ex) {
        if (Double.isInfinite(x)) {
            return x;
        } else {
            return Double.NaN;
        }
    }
}

Sie können versuchen, eine neue Dezimalformat zu definieren und sie als doppeltes Ergebnis zu einer neuen Doppelvariablen zu verwenden.

Beispiel gegeben, damit Sie verstehen, was ich gerade gesagt habe.

double decimalnumber = 100.2397;
DecimalFormat dnf = new DecimalFormat( "#,###,###,##0.00" );
double roundednumber = new Double(dnf.format(decimalnumber)).doubleValue();

Dies ist in der angeforderten Weise nicht möglich, da es Zahlen mit zwei Dezimalstellen gibt, die nicht genau mit IEEE -Schwimmpunktzahlen ausgedrückt werden können (z. B. 1/10 = 0.1 kann nicht als als ausgedrückt werden Double oder Float). Die Formatierung sollte immer als letzter Schritt vor der Präsentation des Ergebnisses dem Benutzer erfolgen.

Ich denke, Sie fragen, weil Sie sich mit Geldwerten befassen möchten. Es gibt keine Möglichkeit, dies mit Gleitkomma-Zahlen zuverlässig zu tun. Dies bedeutet wahrscheinlich, dass alle Berechnungen in "Cent" anstelle von "Dollar" durchgeführt werden.

double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

    TotalPrice = Double.valueOf(format_2Places.format(TotalPrice));

Sie können das Format wie verwenden hier,

  public static double getDoubleValue(String value,int digit){
    if(value==null){
        value="0";
     }
    double i=0;
     try {
         DecimalFormat digitformat = new DecimalFormat("#.##");
         digitformat.setMaximumFractionDigits(digit);
        return Double.valueOf(digitformat.format(Double.parseDouble(value)));

    } catch (NumberFormatException numberFormatExp) {
        return i;   
    }
}

Wenn Sie Decimalformat (z. B. aufgrund ihrer Effizienz) nicht verwenden möchten und eine allgemeine Lösung möchten, können Sie diese Methode auch ausprobieren, bei der skalierte Rundung verwendet wird:

public static double roundToDigits(double value, int digitCount) {
    if (digitCount < 0)
        throw new IllegalArgumentException("Digit count must be positive for rounding!");

    double factor = Math.pow(10, digitCount);
    return (double)(Math.round(value * factor)) / factor;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top