Frage

Was ich möchte, ist eine Methode zum Konvertieren eines Doubles in einen String, der mit der Half-up-Methode aufrundet – d. h.Wenn die zu rundende Dezimalzahl 5 ist, wird immer auf die vorherige Zahl aufgerundet.Dies ist die Standardmethode zum Runden, die die meisten Menschen in den meisten Situationen erwarten.

Ich möchte auch, dass nur signifikante Ziffern angezeigt werden, d. h.Es sollten keine nachgestellten Nullen vorhanden sein.

Ich weiß, dass eine Methode hierfür die Verwendung von ist String.format Methode:

String.format("%.5g%n", 0.912385);

kehrt zurück:

0.91239

Das ist großartig, aber es zeigt immer Zahlen mit 5 Dezimalstellen an, auch wenn sie nicht signifikant sind:

String.format("%.5g%n", 0.912300);

kehrt zurück:

0.91230

Eine andere Methode ist die Verwendung von DecimalFormatter:

DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);

kehrt zurück:

0.91238

Wie Sie jedoch sehen können, wird dabei eine halbgerade Rundung verwendet.Das heißt, es wird abgerundet, wenn die vorherige Ziffer gerade ist.Was ich möchte, ist Folgendes:

0.912385 -> 0.91239
0.912300 -> 0.9123

Was ist der beste Weg, dies in Java zu erreichen?

War es hilfreich?

Lösung

Verwenden setRoundingMode, setzen Sie die RoundingMode Um Ihr Problem mit der halben Runde ausdrücklich zu behandeln, verwenden Sie das Formatmuster für Ihre erforderliche Ausgabe.

Beispiel:

DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
    Double d = n.doubleValue();
    System.out.println(df.format(d));
}

gibt die Ausgabe:

12
123.1235
0.23
0.1
2341234.2125

Andere Tipps

Annahme value ist ein double, du kannst tun:

(double)Math.round(value * 100000d) / 100000d

Das ist 5 -stellige Präzision. Die Anzahl der Nullen zeigt die Anzahl der Dezimalstellen an.

new BigDecimal(String.valueOf(double)).setScale(yourScale, BigDecimal.ROUND_HALF_UP);

Wird dir a bekommen BigDecimal. Um die Zeichenfolge herauszuholen, nennen Sie das einfach das BigDecimal's toString Methode oder die toPlainString Methode für Java 5+ für eine einfache Formatzeichenfolge.

Beispielprogramm:

package trials;
import java.math.BigDecimal;

public class Trials {

    public static void main(String[] args) {
        int yourScale = 10;
        System.out.println(BigDecimal.valueOf(0.42344534534553453453-0.42324534524553453453).setScale(yourScale, BigDecimal.ROUND_HALF_UP));
    }

Sie können auch die verwenden

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

Um sicherzustellen, dass Sie die Nachverfolgung von 0 haben.

Wie einige andere bemerkt haben, ist die richtige Antwort auch zu verwenden DecimalFormat oder BigDecimal. Schwimmpunkt nicht haben Dezimalstellen, sodass Sie möglicherweise nicht in erster Linie zu einer bestimmten Anzahl von ihnen umgehen können. Sie müssen in einem Dezimalradix arbeiten, und genau das tun diese beiden Klassen.

Ich veröffentliche den folgenden Code als Gegenbeispiel auf alle Antworten in diesem Thread und in der Tat überall in Stackoverflow (und anderswo), die eine Multiplikation empfehlen, gefolgt von Abschnitten, gefolgt von der Teilung. Es ist der Befürworter dieser Technik, zu erklären, warum der folgende Code in über 92% der Fälle die falsche Ausgabe erzeugt.

public class RoundingCounterExample
{

    static float roundOff(float x, int position)
    {
        float a = x;
        double temp = Math.pow(10.0, position);
        a *= temp;
        a = Math.round(a);
        return (a / (float)temp);
    }

    public static void main(String[] args)
    {
        float a = roundOff(0.0009434f,3);
        System.out.println("a="+a+" (a % .001)="+(a % 0.001));
        int count = 0, errors = 0;
        for (double x = 0.0; x < 1; x += 0.0001)
        {
            count++;
            double d = x;
            int scale = 2;
            double factor = Math.pow(10, scale);
            d = Math.round(d * factor) / factor;
            if ((d % 0.01) != 0.0)
            {
                System.out.println(d + " " + (d % 0.01));
                errors++;
            }
        }
        System.out.println(count + " trials " + errors + " errors");
    }
}

Ausgabe dieses Programms:

10001 trials 9251 errors

BEARBEITEN: Um einige Kommentare unten anzusprechen BigDecimal und new MathContext(16) Für den Modulbetrieb wie folgt:

public static void main(String[] args)
{
    int count = 0, errors = 0;
    int scale = 2;
    double factor = Math.pow(10, scale);
    MathContext mc = new MathContext(16, RoundingMode.DOWN);
    for (double x = 0.0; x < 1; x += 0.0001)
    {
        count++;
        double d = x;
        d = Math.round(d * factor) / factor;
        BigDecimal bd = new BigDecimal(d, mc);
        bd = bd.remainder(new BigDecimal("0.01"), mc);
        if (bd.multiply(BigDecimal.valueOf(100)).remainder(BigDecimal.ONE, mc).compareTo(BigDecimal.ZERO) != 0)
        {
            System.out.println(d + " " + bd);
            errors++;
        }
    }
    System.out.println(count + " trials " + errors + " errors");
}

Ergebnis:

10001 trials 4401 errors

Angenommen, Sie haben

double d = 9232.129394d;

Sie können verwenden BigDecimal

BigDecimal bd = new BigDecimal(d).setScale(2, RoundingMode.HALF_EVEN);
d = bd.doubleValue();

oder ohne Bigdecimal

d = Math.round(d*100)/100.0d;

Mit beiden Lösungen d == 9232.13

Sie können die Dezimalformatklasse verwenden.

double d = 3.76628729;

DecimalFormat newFormat = new DecimalFormat("#.##");
double twoDecimal =  Double.valueOf(newFormat.format(d));

Real's Java How-to Beiträge Diese Lösung, die auch für Versionen vor Java 1.6 kompatibel ist.

BigDecimal bd = new BigDecimal(Double.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
double myNum = .912385;
int precision = 10000; //keep 4 digits
myNum= Math.floor(myNum * precision +.5)/precision;

@Milhous: Das Dezimalformat für Runden ist ausgezeichnet:

Sie können auch die verwenden

DecimalFormat df = new DecimalFormat("#.00000");
df.format(0.912385);

Um sicherzustellen, dass Sie die Nachverfolgung von 0 haben.

Ich würde hinzufügen, dass diese Methode sehr gut darin ist, einen tatsächlichen numerischen Rundungsmechanismus bereitzustellen - nicht nur visuell, sondern auch bei der Verarbeitung.

Hypothetisch: Sie müssen einen Rundungsmechanismus in ein GUI -Programm umsetzen. Um die Genauigkeit / Genauigkeit eines Ergebnisausgangs zu ändern, ändern Sie einfach das Hausformat (dh innerhalb der Klammern). So dass:

DecimalFormat df = new DecimalFormat("#0.######");
df.format(0.912385);

würde als Ausgabe zurückkehren: 0.912385

DecimalFormat df = new DecimalFormat("#0.#####");
df.format(0.912385);

würde als Ausgabe zurückkehren: 0.91239

DecimalFormat df = new DecimalFormat("#0.####");
df.format(0.912385);

würde als Ausgabe zurückkehren: 0.9124

Bearbeiten: Auch wenn das Pflegeformat so ist ("#0. ###########") und Sie betreten eine Dezimalzahl, z. zB nach hinterliegende Nullen) und wird zurückkehren:3.1415926 .. Wenn Sie so geneigt sind. Zugegeben, es ist ein wenig ausführlich für den Geschmack einiger Entwickler - aber hey, es hat einen geringen Speicherpfund während der Verarbeitung und ist sehr einfach zu implementieren.

Im Wesentlichen ist die Schönheit von Decimalformat, dass es gleichzeitig das Erscheinungsbild der Saiten sowie das Ausmaß des Rundungspräziationssatzes behandelt. ERGO: Sie erhalten zwei Vorteile für den Preis einer Code -Implementierung. ;))

Sie können die folgende Versorgungsmethode verwenden.

public static double round(double valueToRound, int numberOfDecimalPlaces)
{
    double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
    double interestedInZeroDPs = valueToRound * multipicationFactor;
    return Math.round(interestedInZeroDPs) / multipicationFactor;
}

Hier finden Sie eine Zusammenfassung dessen, was Sie verwenden können, wenn Sie das Ergebnis als Zeichenfolge wünschen:

  1. DecimalFormat#setRoundingMode ():

    DecimalFormat df = new DecimalFormat("#.#####");
    df.setRoundingMode(RoundingMode.HALF_UP);
    String str1 = df.format(0.912385)); // 0.91239
    
  2. BigDecimal#setScale ()

    String str2 = new BigDecimal(0.912385)
        .setScale(5, BigDecimal.ROUND_HALF_UP)
        .toString();
    

Hier ist ein Vorschlag, welche Bibliotheken Sie verwenden können, wenn Sie möchten double als Ergebnis. Ich würde es jedoch nicht für die String -Konvertierung empfehlen, da das Doppel möglicherweise nicht genau darstellen kann, was Sie genau wollen (siehe zB. hier):

  1. Präzision Aus Apache Commons Mathematik

    double rounded = Precision.round(0.912385, 5, BigDecimal.ROUND_HALF_UP);
    
  2. Funktionen von Colt

    double rounded = Functions.round(0.00001).apply(0.912385)
    
  3. Utils von weka

    double rounded = Utils.roundDouble(0.912385, 5)
    

Eine prägnante Lösung:

   public static double round(double value, int precision) {
      int scale = (int) Math.pow(10, precision);
      return (double) Math.round(value * scale) / scale;
  }

Siehe auch, https://stackoverflow.com/a/22186845/212950Dank an jpdymond für das Angebot.

Sie können BigDecimal verwenden

BigDecimal value = new BigDecimal("2.3");
value = value.setScale(0, RoundingMode.UP);
BigDecimal value1 = new BigDecimal("-2.3");
value1 = value1.setScale(0, RoundingMode.UP);
System.out.println(value + "n" + value1);

Verweisen: http://www.javabeat.net/precise-rounding-of-decimals-using-rounding-mode-enumeration/

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

Wenn Sie wirklich Dezimalzahlen für die Berechnung wünschen (und nicht nur für die Ausgabe), verwenden Sie kein Binärbasis-Floating Point-Format wie Double.

Use BigDecimal or any other decimal-based format.

Ich benutze BigDecimal für Berechnungen, aber ich denke, es hängt von der Größe der Zahlen ab, mit denen Sie sich befassen. In den meisten meiner Implementierungen finde ich das Parsen von Doppel oder Ganzzahl bis lang genug für sehr große Zahlberechnungen.

Tatsächlich habe ich kürzlich Parsen-to-Long verwendet, um genaue Darstellungen (im Gegensatz zu Hex-Ergebnissen) in einer GUI für Zahlen zu erhalten, die so groß sind wie ################ ############## Zeichen (als Beispiel).

Da ich keine vollständige Antwort zu diesem Thema gefunden habe, habe ich eine Klasse zusammengestellt, die dies ordnungsgemäß behandeln sollte, mit Unterstützung für:

  • Formatierung: Formatieren Sie leicht ein Doppel zu String mit einer bestimmten Anzahl von Dezimalstellen
  • Parsing: Analysieren Sie den formatierten Wert zurück zum Doppel
  • Gebietsschema: Format und analysieren Sie mit dem Standardgebietsschema
  • Exponentielle Notation: Verwenden Sie die exponentielle Notation nach einer bestimmten Schwelle

Die Verwendung ist ziemlich einfach:

(Für dieses Beispiel verwende ich ein benutzerdefiniertes Gebietsschema)

public static final int DECIMAL_PLACES = 2;

NumberFormatter formatter = new NumberFormatter(DECIMAL_PLACES);

String value = formatter.format(9.319); // "9,32"
String value2 = formatter.format(0.0000005); // "5,00E-7"
String value3 = formatter.format(1324134123); // "1,32E9"

double parsedValue1 = formatter.parse("0,4E-2", 0); // 0.004
double parsedValue2 = formatter.parse("0,002", 0); // 0.002
double parsedValue3 = formatter.parse("3423,12345", 0); // 3423.12345

Hier ist die Klasse:

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Locale;

public class NumberFormatter {

    private static final String SYMBOL_INFINITE           = "\u221e";
    private static final char   SYMBOL_MINUS              = '-';
    private static final char   SYMBOL_ZERO               = '0';
    private static final int    DECIMAL_LEADING_GROUPS    = 10;
    private static final int    EXPONENTIAL_INT_THRESHOLD = 1000000000; // After this value switch to exponential notation
    private static final double EXPONENTIAL_DEC_THRESHOLD = 0.0001; // Below this value switch to exponential notation

    private DecimalFormat decimalFormat;
    private DecimalFormat decimalFormatLong;
    private DecimalFormat exponentialFormat;

    private char groupSeparator;

    public NumberFormatter(int decimalPlaces) {
        configureDecimalPlaces(decimalPlaces);
    }

    public void configureDecimalPlaces(int decimalPlaces) {
        if (decimalPlaces <= 0) {
            throw new IllegalArgumentException("Invalid decimal places");
        }

        DecimalFormatSymbols separators = new DecimalFormatSymbols(Locale.getDefault());
        separators.setMinusSign(SYMBOL_MINUS);
        separators.setZeroDigit(SYMBOL_ZERO);

        groupSeparator = separators.getGroupingSeparator();

        StringBuilder decimal = new StringBuilder();
        StringBuilder exponential = new StringBuilder("0.");

        for (int i = 0; i < DECIMAL_LEADING_GROUPS; i++) {
            decimal.append("###").append(i == DECIMAL_LEADING_GROUPS - 1 ? "." : ",");
        }

        for (int i = 0; i < decimalPlaces; i++) {
            decimal.append("#");
            exponential.append("0");
        }

        exponential.append("E0");

        decimalFormat = new DecimalFormat(decimal.toString(), separators);
        decimalFormatLong = new DecimalFormat(decimal.append("####").toString(), separators);
        exponentialFormat = new DecimalFormat(exponential.toString(), separators);

        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        decimalFormatLong.setRoundingMode(RoundingMode.HALF_UP);
        exponentialFormat.setRoundingMode(RoundingMode.HALF_UP);
    }

    public String format(double value) {
        String result;
        if (Double.isNaN(value)) {
            result = "";
        } else if (Double.isInfinite(value)) {
            result = String.valueOf(SYMBOL_INFINITE);
        } else {
            double absValue = Math.abs(value);
            if (absValue >= 1) {
                if (absValue >= EXPONENTIAL_INT_THRESHOLD) {
                    value = Math.floor(value);
                    result = exponentialFormat.format(value);
                } else {
                    result = decimalFormat.format(value);
                }
            } else if (absValue < 1 && absValue > 0) {
                if (absValue >= EXPONENTIAL_DEC_THRESHOLD) {
                    result = decimalFormat.format(value);
                    if (result.equalsIgnoreCase("0")) {
                        result = decimalFormatLong.format(value);
                    }
                } else {
                    result = exponentialFormat.format(value);
                }
            } else {
                result = "0";
            }
        }
        return result;
    }

    public String formatWithoutGroupSeparators(double value) {
        return removeGroupSeparators(format(value));
    }

    public double parse(String value, double defValue) {
        try {
            return decimalFormat.parse(value).doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return defValue;
    }

    private String removeGroupSeparators(String number) {
        return number.replace(String.valueOf(groupSeparator), "");
    }

}

Nur für den Fall, dass jemand dabei noch Hilfe braucht. Diese Lösung funktioniert perfekt für mich.

private String withNoTrailingZeros(final double value, final int nrOfDecimals) {
return new BigDecimal(String.valueOf(value)).setScale(nrOfDecimals,  BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();

}

Gibt eine zurück String mit der gewünschten Ausgabe.

Das folgende Code -Snippet zeigt, wie n -Ziffern angezeigt werden. Der Trick besteht darin, variable PP auf 1 zu setzen, gefolgt von n Zeros. Im folgenden Beispiel hat der variable PP -Wert 5 Nullen, sodass 5 Ziffern angezeigt werden.

double pp = 10000;

double myVal = 22.268699999999967;
String needVal = "22.2687";

double i = (5.0/pp);

String format = "%10.4f";
String getVal = String.format(format,(Math.round((myVal +i)*pp)/pp)-i).trim();

Wenn Sie verwenden DecimalFormat umwandeln double zu String, Es ist sehr einfach:

DecimalFormat formatter = new DecimalFormat("0.0##");
formatter.setRoundingMode(RoundingMode.HALF_UP);

double num = 1.234567;
return formatter.format(num);

Es gibt einige RoundingMode Die Auswahlwerte zur Auswahl, abhängig von dem Verhalten, das Sie benötigen.

Ich bin hierher gekommen und wollte nur eine einfache Antwort, wie man eine Nummer rundet. Dies ist eine ergänzende Antwort, um dies bereitzustellen.

Wie man eine Nummer in Java rundet

Der häufigste Fall ist die Verwendung Math.round().

Math.round(3.7) // 4

Die Zahlen werden auf die nächste ganze Zahl gerundet. EIN .5 Wert ist abgerundet. Wenn Sie ein anderes Rundungsverhalten benötigen, können Sie einen der anderen verwenden Mathematik Funktionen. Siehe den Vergleich unten.

runden

Wie oben erwähnt, runden dies auf die nächste ganze Zahl. .5 Dezimalstellen runden. Diese Methode gibt eine zurück int.

Math.round(3.0); // 3
Math.round(3.1); // 3
Math.round(3.5); // 4
Math.round(3.9); // 4

Math.round(-3.0); // -3
Math.round(-3.1); // -3
Math.round(-3.5); // -3 *** careful here ***
Math.round(-3.9); // -4

Ceil

Jeder Dezimalwert wird auf die nächste Ganzzahl abgerundet. Es geht zum Ceiling. Diese Methode gibt a zurück double.

Math.ceil(3.0); // 3.0
Math.ceil(3.1); // 4.0
Math.ceil(3.5); // 4.0
Math.ceil(3.9); // 4.0

Math.ceil(-3.0); // -3.0
Math.ceil(-3.1); // -3.0
Math.ceil(-3.5); // -3.0
Math.ceil(-3.9); // -3.0

Boden

Jeder Dezimalwert wird auf die nächste Ganzzahl abgerundet. Diese Methode gibt a zurück double.

Math.floor(3.0); // 3.0
Math.floor(3.1); // 3.0
Math.floor(3.5); // 3.0
Math.floor(3.9); // 3.0

Math.floor(-3.0); // -3.0
Math.floor(-3.1); // -4.0
Math.floor(-3.5); // -4.0
Math.floor(-3.9); // -4.0

Rint

Dies ähnelt der Runde in diesen Dezimalwerten bis zur nächsten Ganzzahl. Im Gegensatz zu round, .5 Werte rund um die gleichmäßige Ganzzahl. Diese Methode gibt a zurück double.

Math.rint(3.0); // 3.0
Math.rint(3.1); // 3.0
Math.rint(3.5); // 4.0 ***
Math.rint(3.9); // 4.0
Math.rint(4.5); // 4.0 ***
Math.rint(5.5); // 6.0 ***

Math.rint(-3.0); // -3.0
Math.rint(-3.1); // -3.0
Math.rint(-3.5); // -4.0 ***
Math.rint(-3.9); // -4.0
Math.rint(-4.5); // -4.0 ***
Math.rint(-5.5); // -6.0 ***

Um dies zu erreichen, können wir diesen Formatierer verwenden:

 DecimalFormat df = new DecimalFormat("#.00");
 String resultado = df.format(valor)

oder:

DecimalFormat df = new DecimalFormat("0.00"); :

Verwenden Sie diese Methode, um immer zwei Dezimalstellen zu erhalten:

   private static String getTwoDecimals(double value){
      DecimalFormat df = new DecimalFormat("0.00"); 
      return df.format(value);
    }

Definieren dieser Werte:

91.32
5.22
11.5
1.2
2.6

Mit der Methode können wir diese Ergebnisse erhalten:

91.32
5.22
11.50
1.20
2.60

Demo online.

Ich bin mit der gewählten Antwort einverstanden DecimalFormat --- oder alternativ BigDecimal.

Bitte lesen Sie Aktualisieren unten zuerst!

Wenn Sie jedoch Tun Ich möchte den doppelten Wert runden und a erhalten double Wertergebnis, das Sie verwenden können org.apache.commons.math3.util.Precision.round(..) wie oben erwähnt.Die Implementierung verwendet BigDecimal, ist langsam und erzeugt Müll.

Eine ähnliche, aber schnelle und müllfreie Methode bietet die DoubleRounder Dienstprogramm in der decimal4j-Bibliothek:

 double a = DoubleRounder.round(2.0/3.0, 3);
 double b = DoubleRounder.round(2.0/3.0, 3, RoundingMode.DOWN);
 double c = DoubleRounder.round(1000.0d, 17);
 double d = DoubleRounder.round(90080070060.1d, 9);
 System.out.println(a);
 System.out.println(b);
 System.out.println(c);
 System.out.println(d);

Wird ausgegeben

 0.667
 0.666
 1000.0
 9.00800700601E10

Sehenhttps://github.com/tools4j/decimal4j/wiki/DoubleRounder-Utility

Haftungsausschluss: Ich bin am decimal4j-Projekt beteiligt.

Aktualisieren:Wie @iaforek betonte, liefert DoubleRounder manchmal kontraintuitive Ergebnisse.Der Grund liegt darin, dass eine mathematisch korrekte Rundung durchgeführt wird.Zum Beispiel DoubleRounder.round(256.025d, 2) wird auf 256,02 abgerundet, da der als 256,025d dargestellte Doppelwert etwas kleiner als der rationale Wert 256,025 ist und daher abgerundet wird.

Anmerkungen:

  • Dieses Verhalten ist dem des sehr ähnlich BigDecimal(double) Konstruktor (aber nicht zu valueOf(double) welches den String-Konstruktor verwendet).
  • Das Problem kann umgangen werden, indem man zuerst einen doppelten Rundungsschritt auf eine höhere Genauigkeit durchführt, aber es ist kompliziert und ich gehe hier nicht auf die Details ein

Aus diesen Gründen und allem, was oben in diesem Beitrag erwähnt wurde, habe ich Ich kann die Verwendung von DoubleRounder nicht empfehlen.

Wenn Sie eine Technologie mit einem minimalen JDK verwenden. Hier ist ein Weg ohne Java -Bibliotheken:

double scale = 100000;    
double myVal = 0.912385;
double rounded = (int)((myVal * scale) + 0.5d) / scale;

Decimalformat ist die beste Möglichkeit, umzugeben, aber ich bevorzuge es nicht. Ich mache das immer die ganze Zeit, weil es den Doppelwert zurückgibt. Ich kann es also mehr als nur ausgeben.

Math.round(selfEvaluate*100000d.0)/100000d.0;

ODER

Math.round(selfEvaluate*100000d.0)*0.00000d1;

Wenn Sie einen großen Dezimalstellenwert benötigen, können Sie stattdessen BigDecimal verwenden. Wie auch immer .0 ist wichtig. Ohne sie gibt die Rundung von 0,33333D5 0,33333 zurück und nur 9 Ziffern sind zulässig. Die zweite Funktion ohne .0 hat Probleme mit 0,30000 Return 0,30000000000000004.

Wo dp = dezimaler Ort, den Sie wollen, und Wert ist ein Doppel.

    double p = Math.pow(10d, dp);

    double result = Math.round(value * p)/p;

Denken Sie daran, dass String.Format () und DecimalFormat unter Verwendung des Standardgebiets die Zeichenfolge erstellen. Sie können also eine formatierte Nummer mit DOT oder Comma als Trennzeichen zwischen Ganzzahl und Dezimaleilen schreiben. Um sicherzustellen, dass sich die abgerundete Zeichenfolge in dem Format befindet, in dem Sie Java.Text.NumberFormat als SO verwenden möchten:

  Locale locale = Locale.ENGLISH;
  NumberFormat nf = NumberFormat.getNumberInstance(locale);
  // for trailing zeros:
  nf.setMinimumFractionDigits(2);
  // round to 2 digits:
  nf.setMaximumFractionDigits(2);

  System.out.println(nf.format(.99));
  System.out.println(nf.format(123.567));
  System.out.println(nf.format(123.0));

Drucken in englischem Gebietsschema (unabhängig von Ihrem Gebietsschema): 0,99 123,57 123.00

Das Beispiel stammt von Farenda - So konvertieren Sie doppelt in die richtige String.

Wenn Sie 5 oder N -Anzahl der Dezimalzahl in Betracht ziehen. Kann diese Antwort sein, lösen Sie Ihr Problem.

    double a = 123.00449;
    double roundOff1 = Math.round(a*10000)/10000.00;
    double roundOff2 = Math.round(roundOff1*1000)/1000.00;
    double roundOff = Math.round(roundOff2*100)/100.00;

    System.out.println("result:"+roundOff);

Ausgabe wird sein: 123.01
Dies kann mit Schleifen und rekursiver Funktion gelöst werden.

Im Allgemeinen erfolgt die Rundung durch Skalierung: round(num / p) * p

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */
double RoundCorrect(double num, int precision) {
    double c = 0.5 * EPSILON * num;
//  double p = Math.pow(10, precision); //slow
    double p = 1; while (precision--> 0) p *= 10;
    if (num < 0)
        p *= -1;
    return Math.round((num + c) * p) / p;
}

// testing edge cases
RoundCorrect(1.005, 2);   // 1.01 correct
RoundCorrect(2.175, 2);   // 2.18 correct
RoundCorrect(5.015, 2);   // 5.02 correct

RoundCorrect(-1.005, 2);  // -1.01 correct
RoundCorrect(-2.175, 2);  // -2.18 correct
RoundCorrect(-5.015, 2);  // -5.02 correct
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top