Un doble de 64 bits puede representar un entero +/- 2 53 exactamente
Dado este hecho, elijo usar un tipo doble como tipo único para todos mis tipos, ya que mi número entero más grande es de 32 bits sin signo.
Pero ahora tengo que imprimir estos pseudo enteros, pero el problema es que también están mezclados con dobles reales.
Entonces, ¿cómo imprimo estos dobles muy bien en Java?
Yo he tratado String.format("%f", value)
, que está cerca, excepto que obtengo muchos ceros finales para valores pequeños.
Aquí hay un ejemplo de salida de %f
232.00000000 0.18000000000 1237875192.0 4.5800000000 0.00000000 1.23450000
Lo que quiero es:
232 0,18 1237875192 4.58 0 0 1.2345
Claro que puedo escribir una función para recortar esos ceros, pero eso es una gran pérdida de rendimiento debido a la manipulación de cadenas. ¿Puedo hacerlo mejor con otro código de formato?
EDITAR
Las respuestas de Tom E. y Jeremy S. son inaceptables ya que ambos redondean arbitrariamente a 2 decimales. Por favor, comprenda el problema antes de responder.
EDITAR 2
Tenga en cuenta que String.format(format, args...)
es dependiente de la localización (ver respuestas a continuación).
System.out.println("YOUR STRING" + YOUR_DOUBLE_VARIABLE);
Respuestas:
Si la idea es imprimir enteros almacenados como dobles como si fueran enteros, y de lo contrario imprimir los dobles con la precisión mínima necesaria:
Produce:
Y no se basa en la manipulación de cadenas.
fuente
double
mayor que el máximoint
. Incluso conlong
eso todavía fallaría para un gran número. Además, devolverá una Cadena en forma exponencial, por ejemplo, "1.0E10", para valores grandes, que probablemente no sea lo que el autor de la pregunta desea. Use en%f
lugar de%s
en la segunda cadena de formato para arreglar eso.%f
. La respuesta es específica para la situación descrita y el resultado deseado. El OP sugirió que su valor máximo era un int sin signo de 32 bits, lo que entendí queint
era aceptable (el unsigned no existía realmente en Java y ningún ejemplar era problemático), pero cambiarint
along
es una solución trivial si la situación es diferente.String.format("%s",d)
??? Hable sobre gastos generales innecesarios. UsoDouble.toString(d)
. Lo mismo para el otro:Long.toString((long)d)
.%s
no funciona con configuraciones regionales. En alemán, usamos un "," en lugar de un "." en números decimales MientrasString.format(Locale.GERMAN, "%f", 1.5)
devuelve "1.500000",String.format(Locale.GERMAN, "%s", 1.5)
devuelve "1.5" - con un ".", Que es falso en idioma alemán. ¿Existe una versión local dependiente de "% s" también?Como se señaló en los comentarios, esta no es la respuesta correcta a la pregunta original.
Dicho esto, es una forma muy útil de formatear números sin ceros finales innecesarios.
fuente
fuente
En breve:
Si desea deshacerse de los ceros finales y los problemas de configuración regional, debe usar:
Explicación:
Por qué otras respuestas no me convenían:
Double.toString()
oSystem.out.println
oFloatingDecimal.toJavaFormatString
utiliza notación científica si doble es menos de 10 ^ -3 o mayor que o igual a 10 ^ 7mediante el uso
%f
, la precisión decimal predeterminada es 6, de lo contrario, puede codificarla pero resulta en ceros adicionales agregados si tiene menos decimales. Ejemplo:usando
setMaximumFractionDigits(0);
o%.0f
eliminando cualquier precisión decimal, lo cual está bien para enteros / largos pero no para el dobleAl usar DecimalFormat, usted es dependiente local. En francés, el separador decimal es una coma, no un punto:
El uso de la configuración regional INGLÉS asegura que obtenga un punto para el separador decimal, donde sea que se ejecute su programa
¿Por qué usar 340 entonces para
setMaximumFractionDigits
?Dos razones :
setMaximumFractionDigits
acepta un número entero pero su implementación tiene un máximo de dígitos permitidos de losDecimalFormat.DOUBLE_FRACTION_DIGITS
cuales es igual a 340Double.MIN_VALUE = 4.9E-324
así que con 340 dígitos está seguro de no redondear su precisión doble y sueltafuente
0
lugar de#.
DecimalFormat.DOUBLE_FRACTION_DIGITS
pero está utilizando el valor 340, que luego proporciona un comentario para mostrar que es igualDecimalFormat.DOUBLE_FRACTION_DIGITS
. ¿Por qué no usar la constante?Por qué no:
Esto debería funcionar con los valores extremos admitidos por Double. Rendimientos:
fuente
"%s"
básicamente llamad.toString()
pero no funciona conint
o sid==null
.En mi máquina, la siguiente función es aproximadamente 7 veces más rápida que la función proporcionada por la respuesta de JasonD , ya que evita
String.format
:fuente
Mis 2 centavos:
fuente
return String.format(Locale.US, (n % 1 == 0 ? "%.0f" : "%.1f"), n);
.No, no importa.
La pérdida de rendimiento debido a la manipulación de cadenas es cero.
Y aquí está el código para recortar el final después
%f
fuente
Use un
DecimalFormat
ysetMinimumFractionDigits(0)
fuente
setMaximumFractionDigits(2)
ysetGroupingUsed(false)
(OP no lo menciona, pero por ejemplo parece que es obligatorio). Además, un pequeño caso de prueba no duele ya que es trivial en este caso. Aún así, como creo que es la solución más simple, unfuente
Tenga en cuenta que
String.format(format, args...)
es dependiente de la localización , ya que da formato utilizando configuración regional predeterminada del usuario, que es, probablemente con comas y espacios incluso en el interior como el 123 456 789 o 123,456.789 , que no puede ser exactamente lo que usted espera.Puede preferir usar
String.format((Locale)null, format, args...)
.Por ejemplo,
huellas dactilares
y esto es lo que
String.format(format, args...)
hará en diferentes países.EDITAR Ok, ya que ha habido una discusión sobre formalidades:
fuente
Hice una
DoubleFormatter
conversión eficiente de una gran cantidad de valores dobles a una cadena agradable / presentable:Aquí el código:
Nota: Usé 2 funciones de la biblioteca GUAVA. Si no usa GUAVA, codifíquelo usted mismo:
fuente
Este hará el trabajo bien, sé que el tema es antiguo, pero estaba luchando con el mismo problema hasta que llegué a esto. Espero que alguien lo encuentre útil.
fuente
fuente
fuente
Respuesta tardía pero ...
Dijiste que eliges almacenar tus números con el tipo doble . Creo que esta podría ser la raíz del problema porque te obliga a almacenar números enteros en dobles (y, por lo tanto, perder la información inicial sobre la naturaleza del valor). ¿Qué hay de almacenar sus números en instancias del Número? clase (superclase de Double y Integer) y confiar en el polimorfismo para determinar el formato correcto de cada número?
Sé que puede no ser aceptable refactorizar una parte completa de su código debido a eso, pero podría producir la salida deseada sin código / conversión / análisis adicional.
Ejemplo:
Producirá el siguiente resultado:
fuente
Esto es lo que se me ocurrió:
Un forro simple, solo se envía a int si realmente necesita
fuente
Precio de formato con agrupación, redondeo, sin ceros innecesarios (en doble).
Reglas:
2.0000 = 2; 1.0100000 = 1.01
)2.010 = 2.01; 0.20 = 0.2
)1.994 = 1.99; 1.995 = 2; 1.006 = 1.01; 0.0006 -> 0
)0
(null/-0 = 0
)$
(= $56/-$56
)101101.02 = $101,101.02
)Más ejemplos:
Escrito en Kotlin como una divertida extensión de Double (causa utilizada en Android), pero se puede convertir a Java fácilmente, ya que se usaron clases java.
Cómo utilizar:
Acerca de DecimalFormat : https://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
fuente
Tuve que usar esta causa
d == (long)d
me estaba infringiendo en el informe del sonarfuente
Este es el resultado de algunas pruebas:
fuente
Aquí hay dos formas de lograrlo. Primero, la forma más corta (y probablemente mejor):
Y aquí está la forma más larga y probablemente peor:
fuente
Para Kotlin puedes usar extensiones como:
fuente
Aquí hay otra respuesta que tiene una opción para agregar decimal SOLO SI el decimal no fuera cero.
fuente
Aquí hay una respuesta que realmente funciona (combinación de diferentes respuestas aquí)
fuente
Sé que este es un hilo muy antiguo ... Pero creo que la mejor manera de hacerlo es la siguiente:
Salida:
El único problema es el último donde no se elimina .0. Pero si puede vivir con eso, entonces esto funciona mejor. % .2f lo redondeará a los últimos 2 dígitos decimales. También lo hará DecimalFormat. Si necesita todos los lugares decimales pero no los ceros finales, entonces esto funciona mejor.
fuente
System.out.println(new java.text.DecimalFormat("#.##").format(1.0005));
se imprimirá1
Esto hará que la cadena deje caer los colas 0-s.
fuente