Domanda

Ho un valore Double = 1.068879335 voglio arrotondare in su con due soli valori decimali come 1,07.

ho provato come questo

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

questo mi sta dando questa seguente eccezione

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

qualcuno può dirmi che cosa è sbagliato con il mio codice.

finalmente ho bisogno del finalValue = 1.07;

È stato utile?

Soluzione

Si noti la virgola nella stringa: "1,07". DecimalFormat utilizza una stringa separatore locale-specifico, mentre Double.parseDouble() no. Come vi capita di vivere in un paese dove il separatore decimale è "" non si può analizzare il proprio numero di schiena.

Tuttavia, è possibile utilizzare lo stesso DecimalFormat per analizzare indietro:

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

Ma si dovrebbe davvero fare questo, invece:

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

Nota: Come è stato sottolineato, si dovrebbe usare in virgola mobile se non è necessario un controllo preciso sulla precisione. (Calcoli finanziari ne è l'esempio principale di quando non per usarli.)

Altri suggerimenti

Live @ soluzione di Sergey, ma con divisione di interi.

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

stampe

23.8764367843 rounded is 23.88

EDIT: Come Sergey fa notare, non ci dovrebbe essere alcuna differenza tra multipling doppia * int e doppia doppia * e dividendo doppia / int e doppia / doppia. Non riesco a trovare un esempio in cui il risultato è diverso. Tuttavia su x86 / x64 e altri sistemi c'è un'istruzione specifica il codice macchina per valori int, doppi misti che credo gli usi JVM.

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

Stampa

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

Il problema è che si utilizza un formattatore localizzante che genera locale-specifico punto decimale, che è "" nel tuo caso. Ma Double.parseDouble () si aspetta doppia letterale non localizzato. Si potrebbe risolvere il problema utilizzando un locale specifico metodo di analisi o modificando internazionali del formattatore a qualcosa che usi "" come punto decimale. O ancora meglio, evitare inutili formattazione utilizzando qualcosa di simile:

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

C'è qualcosa di fondamentalmente sbagliato con quello che stai cercando di fare. Binary valori-points galleggianti no sono cifre decimali. Non è possibile per significato primo round a un dato numero di cifre decimali, perché la maggior parte dei valori decimali "rotondo" semplicemente non può essere rappresentato come una frazione binaria. Quale è il motivo per cui non si dovrebbe mai usare float o double per rappresentare i soldi.

Quindi, se volete cifre decimali nel risultato, questo risultato deve essere un String (che avete già ottenuto con la DecimalFormat), oppure un BigDecimal (che ha un metodo setScale() che fa esattamente quello che vuoi). In caso contrario, il risultato non può essere quello che vuoi che sia.

Il Floating-Point Guida per ulteriori informazioni.

Prova questo: org.apache.commons.math3.util.Precision.round (doppia x, int precisione)

Vedere: http: //commons.apache .org / corretto / commons-math / apidocs / org / apache / comuni / math3 / util / Precision.html

Apache Commons Matematica Biblioteca homepage è: http://commons.apache.org/proper/commons-math/index.html

L'Implementazione interna di questo metodo è il seguente:

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

Si potrebbe provare la definizione di una nuova DecimalFormat e di utilizzarlo come un risultato doppio ad una nuova doppia variabile.

Esempio dato per farvi capire quello che ho appena detto.

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

Questo non è possibile nel modo richiesto perché ci sono numeri con cifre decimali due che non possono essere espressi esattamente utilizzando i numeri in virgola mobile IEEE (ad esempio 1/10 = 0,1 non può essere espresso come una Double o Float). La formattazione dovrebbe sempre accadere come l'ultimo passo prima di presentare il risultato per l'utente.

Credo che si sta chiedendo perché si vuole trattare con i valori monetari. Non v'è alcun modo per farlo in modo affidabile con numeri in virgola mobile, dovreste passare ad aritmetica a virgola fissa. Questo probabilmente significa fare tutti i calcoli in "centesimi" invece di "dollari".

double TotalPrice=90.98989898898;

  DecimalFormat format_2Places = new DecimalFormat("0.00");

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

È possibile utilizzare il formato come qui ,

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

Se non si desidera utilizzare DecimalFormat (ad esempio a causa della sua efficienza) e si desidera una soluzione generale, si potrebbe anche provare questo metodo che usi scalato arrotondamento:

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top