2012-07-15 31 views
10

dire che abbiamo un valore doppio di 12345.6789 (dovrebbe essere dinamico)Come estrarre cifre decimali di doppia/BigDecimal

Ora il requisito è diviso il numero e ottenere le cifre decimali e cifre frazionarie, che sarebbe:

double number = 12345.6789; 
int decimal = 12345; 
int fractional = 6789; 

Ho ottenuto la parte decimale risolvere, ma potresti dare un suggerimento sulla parte frazionaria? Molte grazie.

+1

È necessario decidere se stai cercando per la parte frazionaria della rappresentazione * * stampata, o se siete disposti ad accettare la disparità apparente della precisione nella rappresentazione binaria effettiva. – seh

+0

@seh c'è una differenza che il frazionario dovrebbe contenere solo cifre senza la puntura. – Dreamer

+0

L'unico modo è impostare il numero di decimali con cui lavorare ... Esempio con 2 decimali: 0.01 sarebbe 1, e 0.10 sarebbe 10. Guarda la mia risposta. – marcolopes

risposta

13
double number = 12345.6789; // you have this 
int decimal = (int) number; // you have 12345 
double fractional = number - decimal // you have 0.6789 

Il problema qui è che la parte frazionaria non è scritto nella memoria come "0,6789", ma può avere alcuni "offset", per così dire. Ad esempio, 0.6789 può essere memorizzato come 0.67889999291293929991.

penso che la vostra preoccupazione principale qui non è sempre la parte frazionaria, ma ottenere la parte frazionaria con una certa precisione .

Se vuoi per ottenere i valori esatti avete assegnato a, si può prendere in considerazione questo (sebbene sapessimo, non è una soluzione pulita):

String doubleAsText = "12345.6789"; 
double number = Double.parseDouble(doubleAsText); 
int decimal = Integer.parseInt(doubleAsText.split("\.")[0]); 
int fractional = Integer.parseInt(doubleAsText.split("\.")[1]); 

Ma, come ho detto, questo è non la soluzione più efficiente e più pulita.

+0

Ha bisogno di un argomento String regex per il metodo split. Quindi è necessario utilizzare "\\". rif: http://stackoverflow.com/a/14833048/2000405 –

5

Non puoi fare ciò che vuoi fare in modo esatto.

Un problema è se si dispone del numero 1.05 quale dovrebbe essere il risultato?

double number = 1.05; 
int decimal = 1; 
int fractional = 5; // Oops! "1.05" and "1.5" give the same result. 

Che ne dici di questo?

int fractional = 05; // Still not correct. This is an octal number. 

Un altro problema è che il doppio tipo non può rappresentare esattamente 12345.6789. Invece memorizza un numero leggermente diverso. Questo è chiamato errore di rappresentazione. Quindi la parte frazionale non sarà in realtà 6789. Invece puoi arrotondarlo ad un numero di cifre decimali.

int fractional = (int)Math.round((number - decimal) * 1000); 
+0

Non funzionerà mai tutto il tempo in quanto la parte frazionaria può avere più di 4 cifre :) – GETah

+0

@Mark Byers ti ringrazia per la soluzione, ma per quanto riguarda la parte frazione è dinamica, quindi non sappiamo per quanto tempo è così la soluzione * 1000 potrebbe non funzionare. Se il doppio è 12345.678 allora diventa * 100. – Dreamer

+2

@Subarule: Non ti ho dato una soluzione, ti ho dato una spiegazione del perché non può essere fatto senza modificare i requisiti. Quale requisito sei disposto a cambiare? –

2

È possibile convertire in String, trovare il punto decimale, ottenere la stringa e poi riconvertire Integer.

String numberStr = Double.toString(number); 
String fractionalStr = numberStr.substring(numberStr.indexOf('.')+1); 
int fractional = Integer.valueOf(fractionalStr); 
2

È necessario decidere quanti decimali supportare. Io uso questo metodo:

int decimals = 2; 
BigDecimal value = new BigDecimal(123.45).setScale(decimals, RoundingMode.HALF_EVEN); 
BigInteger INTEGER = value.abs().toBigInteger(); 
//(value - INTEGER) * (10^decimais) 
BigInteger DECIMAL = ((value.subtract(new BigDecimal(INTEGER))).multiply(new BigDecimal(10).pow(decimals))).toBigInteger(); 
Problemi correlati