¿Cómo imprimo un valor doble sin notación científica usando Java?

7 minutos de lectura

¿Como imprimo un valor doble sin notacion cientifica usando Java
Despreciable

Quiero imprimir un valor doble en Java sin forma exponencial.

double dexp = 12345678;
System.out.println("dexp: "+dexp);

Muestra esta notación E: 1.2345678E7.

Quiero que lo imprima así: 12345678

¿Cuál es la mejor manera de prevenir esto?

¿Como imprimo un valor doble sin notacion cientifica usando Java
eric leschinski

Java previene la notación E en un doble:

Cinco formas diferentes de convertir un doble en un número normal:

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class Runner {
    public static void main(String[] args) {
        double myvalue = 0.00000021d;

        //Option 1 Print bare double.
        System.out.println(myvalue);

        //Option2, use decimalFormat.
        DecimalFormat df = new DecimalFormat("#");
        df.setMaximumFractionDigits(8);
        System.out.println(df.format(myvalue));

        //Option 3, use printf.
        System.out.printf("%.9f", myvalue);
        System.out.println();

        //Option 4, convert toBigDecimal and ask for toPlainString().
        System.out.print(new BigDecimal(myvalue).toPlainString());
        System.out.println();

        //Option 5, String.format 
        System.out.println(String.format("%.12f", myvalue));
    }
}

Este programa imprime:

2.1E-7
.00000021
0.000000210
0.000000210000000000000001085015324114868562332958390470594167709350585
0.000000210000

Que son todos del mismo valor.

Consejo profesional: si está confundido acerca de por qué esos dígitos aleatorios aparecen más allá de un cierto umbral en el valor doble, este video explica: computerphile ¿por qué 0.1+0.2 igual 0.30000000000001?

http://youtube.com/watch?v=PZRI1IfStY0

  • Simplemente nos dice cómo imprimir el valor doble. ¿Qué pasa si quiero devolverlo como JSON?

    – Fakipo

    28 de septiembre de 2020 a las 11:48

  • Escribí: DecimalFormat df = new DecimalFormat("#,###"); df.setMaximumFractionDigits(340); String str = df.format(dbl); pero cuando paso 1234567890.0123456789 como el valor doble, el valor de retorno se convierte en 1,234,567,890.0123458. Del mismo modo, cuando paso 12345678.0123456789vuelve 12,345,678.01234568. Puede ver que se pierde la precisión fraccionaria. pero cuando paso 12345678.899vuelve 12.345.678,899. Esta vez se mantiene la precisión. ¿Por qué sucede esto al azar? ¿Cómo puedo asegurarme de que la precisión siga siendo correcta siempre? Por favor, ayuda a resolverlo.

    – priyamthéone

    hace 10 horas

1646974270 342 ¿Como imprimo un valor doble sin notacion cientifica usando Java
NPE

podrías usar printf() con %f:

double dexp = 12345678;
System.out.printf("dexp: %f\n", dexp);

Esto se imprimirá dexp: 12345678.000000. Si no quieres la parte fraccionaria, usa

System.out.printf("dexp: %.0f\n", dexp);

0 en %.0f significa 0 lugares en la parte fraccionaria, es decir, ninguna parte fraccionaria. Si desea imprimir una parte fraccionaria con el número deseado de lugares decimales, en lugar de 0, solo proporcione el número como este %.8f. Por defecto, la parte fraccionaria se imprime hasta 6 decimales.

Esto utiliza el lenguaje especificador de formato explicado en el documentación.

El valor por defecto toString() el formato utilizado en su código original está explicado aquí.

  • pero se mostró dexp: 12345681.000000 que es un valor incorrecto. Y en realidad, después de eso, quiero mostrarlo en mi página web donde se muestra así 1.2345678E7.¿Hay alguna forma de almacenarlo en cualquier doble como 12345678 y de alguna otra manera?

    – Despreciable

    19 de abril de 2013 a las 5:56

  • @despicable: es posible que haya estado mirando la versión anterior e incompleta de la respuesta. Intenta recargar la página. Debería haber un párrafo sobre %.0f.

    – ENP

    19 de abril de 2013 a las 5:57


  • @despicable podría almacenar dexp como un int para que pueda usarlo fácilmente en ambos sentidos

    – Justin

    19 de abril de 2013 a las 5:58

  • REDONDEA EL NÚMERO

    – confundir

    12 de marzo de 2015 a las 16:15

  • %.0f redondea el número. ¿Hay alguna manera de simplemente descartar los ceros finales?

    – Nur Shomik

    23 de enero de 2017 a las 19:59

1646974270 200 ¿Como imprimo un valor doble sin notacion cientifica usando Java
JBE

En breve:

Si desea deshacerse de los ceros finales y los problemas de configuración regional, debe usar:

double myValue = 0.00000021d;

DecimalFormat df = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
df.setMaximumFractionDigits(340); // 340 = DecimalFormat.DOUBLE_FRACTION_DIGITS

System.out.println(df.format(myValue)); // Output: 0.00000021

Explicación:

Por qué otras respuestas no me convenían:

  • Double.toString() o System.out.println o FloatingDecimal.toJavaFormatString usa notaciones científicas si el doble es menor que 10^-3 o mayor o igual que 10^7
  • Mediante el uso %f, la precisión decimal predeterminada es 6; de lo contrario, puede codificarla, pero se agregarán ceros adicionales si tiene menos decimales. Ejemplo:

    double myValue = 0.00000021d;
    String.format("%.12f", myvalue); // Output: 0.000000210000
    
  • Mediante el uso setMaximumFractionDigits(0); o %.0f elimina cualquier precisión decimal, lo cual está bien para enteros/largos, pero no para el doble:

    double myValue = 0.00000021d;
    System.out.println(String.format("%.0f", myvalue)); // Output: 0
    DecimalFormat df = new DecimalFormat("0");
    System.out.println(df.format(myValue)); // Output: 0
    
  • Al usar DecimalFormat, eres dependiente local. En la configuración regional francesa, el separador decimal es una coma, no un punto:

    double myValue = 0.00000021d;
    DecimalFormat df = new DecimalFormat("0");
    df.setMaximumFractionDigits(340);
    System.out.println(df.format(myvalue)); // Output: 0,00000021
    

    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 DecimalFormat.DOUBLE_FRACTION_DIGITS que es igual a 340
  • Double.MIN_VALUE = 4.9E-324 así que con 340 dígitos estás seguro de no redondear tu doble y perder precisión.

  • cual es tu opinion de new BigDecimal(myvalue).toPlainString() De la descripción en docs.oracle.com/javase/7/docs/api/java/math/…), no es inmediatamente obvio cómo se comporta cuando se le dan diferentes tipos de números, pero elimina la notación científica.

    – Derek Mahar

    07/04/2015 a las 15:22

  • new BigDecimal(0.00000021d).toPlainString() producción 0.0000002100000000000000010850153241148685623329583904705941677093505859375 que no es lo que esperarías…

    – JBE

    7 abr 2015 a las 19:06

  • ¿Alguna idea de cómo usar tu respuesta en Scala? Probablemente sea una cuestión de importaciones apropiadas, pero soy nuevo aquí.

    – jangorecki

    1 de agosto de 2016 a las 16:54

  • BigDecimal.valueOf(0.00000021d).toPlainString() funciona también (usa el constructor String de BigDecimal por eso)

    – marco

    13 de agosto de 2019 a las 0:33

  • Esta respuesta no funciona bien para flotadores: 24.728352f se convierte "24.728351593017578".

    – NateS

    18 de agosto de 2021 a las 1:49

Puedes intentarlo con DecimalFormat. Con esta clase, eres muy flexible al analizar tus números.
Puede establecer exactamente el patrón que desea utilizar.
En tu caso por ejemplo:

double test = 12345678;
DecimalFormat df = new DecimalFormat("#");
df.setMaximumFractionDigits(0);
System.out.println(df.format(test)); //12345678

1646974270 802 ¿Como imprimo un valor doble sin notacion cientifica usando Java
Manuel

Tengo otra solución que involucra toPlainString() de BigDecimal, pero esta vez usando el constructor de cadenas, que se recomienda en el javadoc:

este constructor es compatible con los valores devueltos por Float.toString y Double.toString. Esta es generalmente la forma preferida de convertir un flotante o un doble en un BigDecimal, ya que no sufre la imprevisibilidad del constructor BigDecimal(doble).

Se ve así en su forma más corta:

return new BigDecimal(myDouble.toString()).stripTrailingZeros().toPlainString();

NaN y los valores infinitos deben verificarse adicionalmente, por lo que se ve así en su forma completa:

public static String doubleToString(Double d) {
    if (d == null)
        return null;
    if (d.isNaN() || d.isInfinite())
        return d.toString();

    return new BigDecimal(d.toString()).stripTrailingZeros().toPlainString();
}

Esto también se puede copiar/pegar para que funcione bien con Float.

Para Java 7 y versiones anteriores, esto da como resultado “0.0” para cualquier doble de valor cero, por lo que deberá agregar:

if (d.doubleValue() == 0)
    return "0";

  • He leído innumerables esquemas para convertir un valor doble en una cadena y este es el mejor: breve, sencillo y configurable.

    – Pablo

    17/11/2016 a las 19:47

  • Por qué d.doubleValue() == 0 en lugar de d == 0?

    – Alexéi Fando

    27/10/2017 a las 14:33

  • Porque evita el desempaquetado automático, que me gusta más en esa situación, pero, por supuesto, las opiniones pueden diferir al respecto. Si está en Java 8 (9 probablemente sea lo mismo), puede omitir esas 2 líneas por completo.

    – Manuel

    30/10/2017 a las 15:40


  • Acabo de probar con Java 9, esas 2 líneas también se pueden omitir en 9.

    – Manuel

    30 de octubre de 2017 a las 16:04

¿Como imprimo un valor doble sin notacion cientifica usando Java
eric leschinski

Esto funcionará siempre que su número sea un número entero:

double dnexp = 12345678;
System.out.println("dexp: " + (long)dexp);

Si la variable doble tiene precisión después del punto decimal, la truncará.

  • He leído innumerables esquemas para convertir un valor doble en una cadena y este es el mejor: breve, sencillo y configurable.

    – Pablo

    17/11/2016 a las 19:47

  • Por qué d.doubleValue() == 0 en lugar de d == 0?

    – Alexéi Fando

    27/10/2017 a las 14:33

  • Porque evita el desempaquetado automático, que me gusta más en esa situación, pero, por supuesto, las opiniones pueden diferir al respecto. Si está en Java 8 (9 probablemente sea lo mismo), puede omitir esas 2 líneas por completo.

    – Manuel

    30/10/2017 a las 15:40


  • Acabo de probar con Java 9, esas 2 líneas también se pueden omitir en 9.

    – Manuel

    30 de octubre de 2017 a las 16:04

El compilador Java/Kotlin convierte cualquier valor mayor que 9999999 (mayor o igual a 10 millones) a notación científica, es decir. notación epsilion.

Ej: 12345678 se convierte en 1.2345678E7

Utilice este código para evitar la conversión automática a notación científica:

fun setTotalSalesValue(String total) {
        var valueWithoutEpsilon = total.toBigDecimal()
        /* Set the converted value to your android text view using setText() function */
        salesTextView.setText( valueWithoutEpsilon.toPlainString() )
    }

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad