Pregunta

Recientemente traté de entender el uso de java.de matemáticas.MathContext pero no pudo entender correctamente.Se utiliza para el redondeo en java.math.BigDecimal.Si sí ¿por qué no se la ronda de los dígitos decimales pero incluso mantisa parte.

A partir de la API de google docs, vine a saber que sigue el estándar especificado en ANSI X3.274-1996 y ANSI X3.274-1996/AM 1-2000 especificaciones pero no llegué a leer en línea.

Por favor, hágamelo saber si usted tiene alguna idea sobre esto.

¿Fue útil?

Solución

@jatan

Gracias por la respuesta.Tiene sentido.¿Puede por favor explicar me MathContext en el contexto de BigDecimal#ronda método.

No hay nada especial acerca de BigDecimal.round() vs cualquier otro BigDecimal método.En todos los casos, la MathContext especifica el número de dígitos significativos y el redondeo de la técnica.Básicamente, hay dos partes de cada MathContext.Hay una precisión, y también hay un RoundingMode.

La precisión de nuevo especifica el número de dígitos significativos.Así que si usted especifique 123 como un número, y pregunte por 2 dígitos significativos, vas a conseguir 120.Podría ser más clara si pensamos en términos de la notación científica.

123 sería 1.23e2 en la notación científica.Si sólo mantener a 2 cifras significativas, entonces se obtiene 1.2e2, o 120.Al reducir el número de dígitos significativos, podemos reducir la precisión con la que podemos especificar un número.

El RoundingMode parte especifica cómo debemos manejar la pérdida de precisión.Para reutilizar el ejemplo, si se utiliza 123 como el número, y pregunte por 2 dígitos significativos, ha reducido su precisión.Con un RoundingMode de HALF_UP (el modo por defecto), 123 se convertirá en 120.Con un RoundingMode de CEILING, usted conseguirá el 130.

Por ejemplo:

System.out.println(new BigDecimal("123.4",
                   new MathContext(4,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.HALF_UP)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(2,RoundingMode.CEILING)));
System.out.println(new BigDecimal("123.4",
                   new MathContext(1,RoundingMode.CEILING)));

Salidas:

123.4
1.2E+2
1.3E+2
2E+2

Se puede ver que tanto la precisión y el modo de redondeo afecta a la salida.

Otros consejos

Para el redondeo sólo la parte fraccionaria de un BigDecimal, retirar el BigDecimal.setScale(int newScale, int roundingMode) método.

E. g.para cambiar un número de tres dígitos después del punto decimal a uno con dos dígitos, y redondeo:

BigDecimal original = new BigDecimal("1.235");
BigDecimal scaled = original.setScale(2, BigDecimal.ROUND_HALF_UP);

El resultado de esto es un BigDecimal con el valor de 1,24 (debido al redondeo de la regla)

Me gustaría añadir aquí, un par de ejemplos.No he encontrado en las respuestas anteriores, pero me parece útil para aquellos que tal vez inducir a error dígitos significativos con el número de decimales.Supongamos, hemos dicho contexto:

MathContext MATH_CTX = new MathContext(3, RoundingMode.HALF_UP);

Para que este código:

BigDecimal d1 = new BigDecimal(1234.4, MATH_CTX);
System.out.println(d1);

es perfectamente claro, que su resultado es 1.23E+3 como los chicos se dijo anteriormente.Primeros dígitos significativos son 123...

Pero lo que en este caso:

BigDecimal d2 = new BigDecimal(0.000000454770054, MATH_CTX);
System.out.println(d2);

su número no será redondeado a 3 lugares después de la coma - para una persona puede no ser intuitivo y vale la pena destacar.En su lugar se redondeará a la primeros 3 dígitos significativos, que en este caso son los "4 5 4".Así, por encima de resultados del código en 4.55E-7 y no en 0.000 como alguien podía esperar.

Ejemplos similares:

BigDecimal d3 = new BigDecimal(0.001000045477, MATH_CTX);
 System.out.println(d3);  // 0.00100

BigDecimal d4 = new BigDecimal(0.200000477, MATH_CTX);
 System.out.println(d4);   // 0.200

BigDecimal d5 = new BigDecimal(0.000000004, MATH_CTX);
    System.out.println(d5); //4.00E-9

Espero que este obvio, pero relevante ejemplo podría ser útil...

Si entiendo correctamente, suena como que usted está esperando el MathContext para controlar la cantidad de dígitos debe ser mantenido después del punto decimal.Eso no es lo que es.Se especifica el número de dígitos a mantener, total.Por lo que si especifica que desea 3 dígitos significativos, eso es todo lo que vas a obtener.

Por ejemplo, este:

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(20)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(10)));

System.out.println(new BigDecimal("1234567890.123456789",
                   new MathContext(5)));

de salida será:

1234567890.123456789
1234567890
1.2346E+9

No es por diversión.En realidad he encontrado algunos en línea ejemplo, que declaró que el uso de MathContext para redondear las cantidades y números almacenados en BigDecimal.

Por ejemplo,

Si MathContext está configurado para tener precision = 2 y rounding mode = ROUND_HALF_EVEN

BigDecimal Number = 0.5294, es redondeado a 0.53

Así que pensé que es una técnica más reciente y que se usaba para el redondeo de propósito.Sin embargo, se convirtió en pesadilla, ya que comenzó a redondeo incluso mentissa parte de número.

Por ejemplo,

Number = 1.5294 se redondea a 1.5

Number = 10.5294 se redondea a 10

Number = 101.5294 se redondea a 100

....y así sucesivamente

Así que esto no es el comportamiento que se espera para el redondeo (como la precisión = 2).

Parece tener cierta lógica, porque a partir de la fraseología puedo decir que lleva dos primeros dígitos (como la precisión es de 2) de número y, a continuación, se anexa 0 hasta el no.de dígitos convertido mismo importe no redondeado (descargue el ejemplo de 101.5294 ...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top