2012-07-15 25 views
10

decir que tenemos un valor doble de 12345.6789 (debe ser dinámico)¿Cómo extraer dígitos fraccionarios de doble/BigDecimal

Ahora el requisito se divide el número y obtener los dígitos decimales y dígitos fraccionarios, que serían:

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

Me sale la parte decimal pero ¿podría darnos una pista sobre la parte fraccionaria? Muchas gracias.

+1

Es necesario decidir si lo que buscas es la parte fraccionaria de la representación impresa * *, o si usted está dispuesto a aceptar la aparente disparidad en la precisión en la representación binaria real. – seh

+0

@seh existe una diferencia en que el fraccionario solo debe contener dígitos sin pinchazo. – Dreamer

+0

La única forma es establecer el número de decimales para trabajar con ... Ejemplo con 2 decimales: 0.01 sería 1 y 0.10 sería 10. Mira mi respuesta. – marcolopes

Respuesta

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

El problema aquí es que la parte fraccionaria no está escrita en la memoria como "0.6789", pero puede tener ciertas "compensaciones", por así decirlo. Por ejemplo, 0.6789 se puede almacenar como 0.67889999291293929991.

Creo que su principal preocupación aquí no está recibiendo la parte fraccionaria, pero conseguir la parte fraccionaria con una cierta precisión .

Si desea obtener los valores exactos que le asignó a, es posible que desee considerar este (Altho, no es una solución limpia):

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

Pero, como ya he dicho, esto es no es la solución más eficiente y limpia.

+0

Necesita un argumento de cadena regex para el método de división. Entonces necesitas usar "\\". ref: http://stackoverflow.com/a/14833048/2000405 –

5

No puede hacer lo que quiere hacer de una manera exacta.

Un problema es si tiene el número 1.05 ¿cuál debería ser el resultado?

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

¿Qué le parece esto?

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

Otro problema es que el tipo de matrimonio no puede representar exactamente 12345.6789. Almacena un número ligeramente diferente en su lugar. Esto se llama error de representación. Entonces, la parte fraccionaria en realidad no será 6789. En cambio, puede redondearlo a una cierta cantidad de decimales.

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

Realmente no funciona todo el tiempo, ya que la parte fraccional puede tener más de 4 dígitos :) – GETah

+0

@Mark Byers gracias por la solución, pero ¿qué pasa con la parte de la fracción es dinámica, así que no sabemos cuánto tiempo es así la solución * 1000 puede no estar funcionando. Si el doble es 12345.678, entonces se convierte en * 100. – Dreamer

+2

@Subarule: No le di una solución, le di una explicación de por qué no se puede hacer sin cambiar los requisitos. ¿Qué requisito estás dispuesto a cambiar? –

2

Puede convertir a String, encontrar el punto decimal, obtener la subcadena y luego convertir de nuevo a entero.

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

Debe decidir cuántos decimales apoyar. Yo uso este método:

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(); 
Cuestiones relacionadas