¿Hay una función de biblioteca de Java que se puede utilizar para truncar un número a un número arbitrario de lugares decimales? Por ejemplo.¿Hay alguna función para truncar un doble en java?
SomeLibrary.truncate(1.575, 2) = 1.57
Gracias
¿Hay una función de biblioteca de Java que se puede utilizar para truncar un número a un número arbitrario de lugares decimales? Por ejemplo.¿Hay alguna función para truncar un doble en java?
SomeLibrary.truncate(1.575, 2) = 1.57
Gracias
Try setScale de BigDecimal así:
public static double round(double d, int decimalPlace) {
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
2 comentarios: el 'BigDecimal' ya tiene un constructor tomando' Double'. El OP tampoco parece querer redondearlo a medias, sino simplemente truncarlo (plantarlo). – BalusC
@BalusC: Con respecto a su primer comentario, lo actualicé ... – raoulsson
En realidad, BalusC tiene razón, quiero truncar el valor, sin embargo, su respuesta me llevó en la dirección correcta, así que lo acepto. –
Para la mayoría de los números, usted no será capaz de obtener una representación exacta de xxx.yyyy
a menos que utilice una clase decimal con una precisión garantizada, como BigDecimal.
más fundamentalmente, los dobles no * tienen * decimales, ya que están almacenados como fracciones binarias. –
Para hacerlo 100% confiable, tendrías que pasar el argumento como una cadena, no como un número de coma flotante. Cuando se presenta como una cadena, el código es fácil de escribir. La razón de esto es que
double x = 1.1;
no quiere decir que x realmente evaluar a 1,1, sólo para el número exactamente representable más cercano.
O use BigDecimal, que es una de las razones por las que existe BigDecimal. –
Aún necesita inicializarlo desde la cadena, no desde el doble. –
creó un método para hacerlo.
public double roundDouble(double d, int places) {
return Math.round(d * Math.pow(10, (double) places))/Math.pow(10, (double)places);
}
Hay una en commons-math. Confirmar
http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html
:
public static double round(double x,
int scale)
se implementa utilizando BigDecimal, y está sobrecargado para permitir la especificación de un método de redondeo, por lo que se puede utilizar para truncar, así:
org.apache.commons.math.util.MathUtils.round(1.575, 2,
java.math.BigDecimal.ROUND_DOWN);
Actualización:
En la última versión (Math3), este método está en la clase Precision
. org.apache.commons.math3.util.Precision.round(double x, int scale, int roundingMethod)
En realidad, este tipo de cosas es fácil escribir:
public static double truncate(double value, int places) {
double multiplier = Math.pow(10, places);
return Math.floor(multiplier * value)/multiplier;
}
Tenga en cuenta que es Math.floor, porque Math.round no sería truncar.
Ah, y esto devuelve un doble, porque eso es lo que la mayoría de las funciones en la clase Math devuelve (como Math.pow y Math.floor).
Advertencia: Dobles chupar para mayor precisión. Una de las soluciones BigDecimal debe considerarse primero.
Nota: pow es una función muy costosa. Úselo si el rendimiento no es un problema. –
Me gusta esta solución por simplicidad y claridad. –
No funcionará para truncado (9.62,2) devolverá 9.61 – Mani
Increíble, nadie lo mencionó aún, Java API ha tenido DecimalFormat por edades ahora para este propósito exacto.
Concretamente para el ejemplo dado, el código se vería así: DecimalFormat final df = new DecimalFormat(); df.setMaximumFractionDigits (2); df.format (1.575); La última expresión devuelve una cadena que se debe volver a convertir en una doble. – ubuntudroid
Esto hará todo el año, creo que la pregunta para truncar no es redonda. – Mani
He aquí una breve aplicación que es muchas veces más rápido que usar BigDecimal o Math.pow
private static long TENS[] = new long[19];
static {
TENS[0] = 1;
for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1];
}
public static double round(double v, int precision) {
assert precision >= 0 && precision < TENS.length;
double unscaled = v * TENS[precision];
if(unscaled < Long.MIN_VALUE || unscaled > Long.MAX_VALUE)
return v;
long unscaledLong = (long) (unscaled + (v < 0 ? -0.5 : 0.5));
return (double) unscaledLong/TENS[precision];
}
Eliminar los assert'ions al gusto.;)
El único problema que veo con esto es que está multiplicando el parámetro 'v' por (potencialmente) varias potencias de 10, lo que puede causar un desbordamiento. Claro, el doble valor máximo es alrededor de 10^308 por lo que la mayoría de las personas no lo notarán, sin embargo es posible, lo cual es un comportamiento sorprendente (no se espera que una función de redondeo tenga un desbordamiento al enviar un valor válido). –
Acabo de notar que el método fallará tan pronto como el valor sin escala exceda el tipo "largo", que es mucho antes. Esto podría ser bastante rápido incluso si el parámetro 'v' es pequeño si se solicita la precisión suficiente. –
@UMad Ok, cambió el cheque que debería manejar ambos casos. –
Utilice esta sencilla función
double truncateDouble(double number, int numDigits) {
double result = number;
String arg = "" + number;
int idx = arg.indexOf('.');
if (idx!=-1) {
if (arg.length() > idx+numDigits) {
arg = arg.substring(0,idx+numDigits+1);
result = Double.parseDouble(arg);
}
}
return result ;
}
sólo quiero añadir a ubuntudroid de solución. que lo probamos y no sería redondear hacia abajo, así que tuve que añadir
df.setRoundingMode(RoundingMode.FLOOR);
para que funcione.
basta con quitar la parte fraccionaria
public double trunk(double value){ return value - value % 1; }
posible duplicado de [Ronda un doble a 2 cifras significativas después del punto decimal] (http://stackoverflow.com/questions/2808535/round-a-double -to-2-significant-figures-after-decimal-point) –