Domanda

Sto cercando di sbarazzarsi di simboli inutili dopo decimale separatore del mio valore doppio. Lo sto facendo in questo modo:

DecimalFormat format = new DecimalFormat("#.#####");
value = Double.valueOf(format.format(41251.50000000012343));

Ma quando si esegue questo codice, viene generata:

java.lang.NumberFormatException: For input string: "41251,5"
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
    at java.lang.Double.valueOf(Double.java:447)
    at ...

Per come la vedo, Double.valueOf() grandi opere con le stringhe come "11.1", ma soffoca sulle stringhe come "11,1". Come posso ovviare a questo? C'è un modo più elegante poi qualcosa come

Double.valueOf(format.format(41251.50000000012343).replaceAll(",", "."));

C'è un modo per ignorare il valore di separatore decimale predefinito di classe DecimalFormat? Eventuali altri pensieri?

È stato utile?

Soluzione

Per

  

sbarazzarsi di simboli inutili dopo decimale separatore del mio valore doppio

si fa realtà significa che si desidera round per esempio il 5 ° decimale? Poi basta usare

value = Math.round(value*1e5)/1e5;

(naturalmente si può anche Math.floor(value*1e5)/1e5 se si vuole veramente le altre cifre tagliare)

Altri suggerimenti

Il problema è che il formato decimale converte il valore in una stringa localizzata. Sto indovinando che il separatore decimale predefinito per il locale è con un ','. Questo accade spesso con i locali francesi o altre parti del mondo.

In sostanza ciò che devi fare è creare il data formattata con il '' separatore in modo Double.valueOf può leggere. Come indicato dai commenti, è possibile utilizzare lo stesso formato per analizzare il valore e invece di usare Double.valueOf.

DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("#.#####", symbols);
value = format.parse(format.format(41251.50000000012343));

Il fatto che i vostri usi stringa di formattazione . come separatore decimale, mentre l'eccezione si lamenta di punti , ad un problema Locale; cioè DecimalFormat utilizza un diverso Locale per formattare il numero di aspetta Double.valueOf.

In generale, si dovrebbe costruire un NumberFormat sulla base di una specifica Locale.

Locale myLocale = ...;
NumberFormat f = NumberFormat.getInstance(myLocale);

Dalle JavaDocs di DecimalFormat :

  

Per ottenere un NumberFormat per impostazioni locali specifiche, tra cui la lingua di default, chiamare uno dei metodi di fabbrica di NumberFormat, come getInstance (). In generale, non chiamare i costruttori DecimalFormat direttamente, dal momento che i metodi di fabbrica NumberFormat possono restituire sottoclassi diverse DecimalFormat.

come BalusC punti su , tentare di formattare una doppia come String e quindi analizzare la parte posteriore String al doppio è un odore di codice piuttosto male. Ho il sospetto che si tratta di questioni in cui ci si aspetta un numero a precisione fissa decimale (come ad esempio un importo monetario), ma si esegue in problemi a causa doppio è un numero in virgola mobile, il che significa che molti valori (come 0.1) non possono essere espressa appunto come un doppio / galleggiante. Se questo è il caso, il modo corretto di gestire un numero decimale a precisione fissa è di usare un BigDecimal .

Usa Locale.getDefault() per ottenere il vostro separatore decimale di sistema che è possibile impostare. Non si può avere a diversi separatori allo stesso tempo da quando l'altro è poi di solito usato come seprator per migliaia: 2.001.000,23 <=> 2,001,000.23

Per la ',' al posto del '.', che avrebbe dovuto modificare le impostazioni internazionali.

Per il numero di decimali, l'uso setMaximumFractionDigits(int newValue).

Per il resto, consultare Javadoc .

Sembra che il tuo uso locale una virgola "" come un decimale separation.To ottenere il "" come separatore decimale, si dovrà dichiarare:

DecimalFormat dFormat =new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.ENGLISH));

Non è possibile modificare la rappresentazione interna di double / Double in quel modo.

Se si desidera cambiare la rappresentazione (umana), basta tenere String. Così, lasciare che Double#valueOf() di distanza e usare il risultato di String DecimalFormat#format() nella presentazione. Se mai voglia di fare calcoli con esso, si può sempre trasformare di nuovo ad un vero e proprio Double utilizzando DecimalFormat e Double#valueOf().

A proposito, secondo la vostra lamentano che sto cercando di sbarazzarsi dei simboli inutili dopo decimale separatore del mio valore doppio , siete a conoscenza dei meccanismi interni di numeri in virgola galleggiante? C'è odore un po 'come che si sta utilizzando raddoppia non formattati nello strato di presentazione e che non si rendeva conto che con l'interfaccia utente medio si può semplicemente presentare loro utilizzando DecimalFormat senza la necessità di riconvertire Double.

Un po 'legato a questo, ma non è una risposta alla domanda: tenta di passare a BigDecimal invece di doppie e carri allegorici. Stavo facendo un sacco di problema con confronti su quei tipi e ora sto bene ad andare con BigDecimal.

La vera soluzione è: non utilizzare i numeri in virgola mobile per tutto ciò che ha bisogno di essere contati con precisione:

  • Se avete a che fare con la moneta, non utilizzare un numero doppio di dollari, utilizzare un numero intero di centesimi.
  • Se avete a che fare con le ore di tempo e bisogno di contare quarti d'ora e intervalli di 10 minuti, utilizzare un numero intero di minuti.

Un numero virgola mobile è quasi sempre un'approssimazione di qualche valore reale. Sono adatti per misurazioni e calcolo delle grandezze fisiche (alto grado di precisione) e per artefatti statistici.

Ingannare circa con arrotondamento a virgola mobile a un numero di cifre è un odore di codice:. È uno spreco e non si può mai essere veramente sicuri che il codice funziona correttamente in tutti i casi

La mia funzione di codice:

 private static double arrondi(double number){
         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
         symbols.setDecimalSeparator('.');
         DecimalFormat format = new DecimalFormat("#.#####", symbols);
         return Double.valueOf(format.format(number));
     }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top