2009-07-31 49 views
5

Estoy usando la clase DecimalFormat de Java para imprimir números en notación científica. Sin embargo, hay un problema que tengo. Necesito que las cuerdas sean de longitud fija, independientemente del valor, y el letrero con el poder de diez lo está arrojando. En la actualidad, esto es lo que se ve mi formato como:Java DecimalFormat notación científica Pregunta

DecimalFormat format = new DecimalFormat("0.0E0"); 

Esto me da las siguientes combinaciones: 1.0E1, 1.0E1, -1.0E1, y -1.0E-1.

puedo usar setPositivePrefix para obtener: + 1.0E1, 1.0E1 +, -1.0E1 y -1.0E-1, o lo que me gusta, pero que no afecta a la señal del poder !

¿Hay alguna manera de hacer esto para que pueda tener cadenas de longitud fija? ¡Gracias!

Editar: Ah, entonces no hay forma de hacerlo usando la API existente DecimalFormat de Java API? Gracias por las sugerencias! Creo que debo tener la subclase DecimalFormat porque estoy limitado por la interfaz que ya está instalada.

Respuesta

2

Aquí hay una manera. Hokey, tal vez, pero funciona ...

public class DecimalFormatTest extends TestCase { 
    private static class MyFormat extends NumberFormat { 
     private final DecimalFormat decimal; 

     public MyFormat(String pattern) { 
      decimal = new DecimalFormat(pattern); 
     } 

     public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { 
      StringBuffer sb = new StringBuffer(); 
      sb.append(modified(Math.abs(number) > 1.0, decimal.format(number, toAppendTo, pos).toString())); 
      return sb; 
     } 

     private String modified(boolean large, String s) { 
      return large ? s.replace("E", "E+") : s; 
     } 

     public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { 
      StringBuffer sb = new StringBuffer(); 
      sb.append(modified(true, decimal.format(number, toAppendTo, pos).toString())); 
      return sb; 
     } 

     public Number parse(String source, ParsePosition parsePosition) { 
      return decimal.parse(source, parsePosition); 
     } 

     public void setPositivePrefix(String newValue) { 
      decimal.setPositivePrefix(newValue); 
     } 
    } 
    private MyFormat format; 

    protected void setUp() throws Exception { 
     format = new MyFormat("0.0E0"); 
     format.setPositivePrefix("+"); 
    } 

    public void testPositiveLargeNumber() throws Exception { 
     assertEquals("+1.0E+2", format.format(100.0)); 
    } 

    public void testPositiveSmallNumber() throws Exception { 
     assertEquals("+1.0E-2", format.format(0.01)); 
    } 

    public void testNegativeLargeNumber() throws Exception { 
     assertEquals("-1.0E+2", format.format(-100.0)); 
    } 

    public void testNegativeSmallNumber() throws Exception { 
     assertEquals("-1.0E-2", format.format(-0.01)); 
    } 
} 

alternativa usted puede subclase DecimalFormat, pero me resulta generalmente más limpio, no a la subclase de las clases concretas.

2

Podría utilizar printf() lugar:

Format format = new DecimalFormat("0.0E0"); 
Double d = new Double(.01); 
System.out.println(format.format(d)); 
System.out.printf("%1.1E\n", d); 
d = new Double(100); 
System.out.println(format.format(d)); 
System.out.printf("%1.1E\n", d); 

Salida:

1.0E-2 
1.0E-02 
1.0E2 
1.0E+02 

Si necesita salida a un String su lugar, puede utilizar la información proporcionada en Formatted Printing for Java (sprintf) de hacer eso.

EDIT: Wow, eso PrintfFormat() cosa es enorme y parece ser innecesaria:

OutputStream b = new ByteArrayOutputStream(); 
PrintStream p = new PrintStream(b); 
p.printf("%1.1E", d); 
System.out.println(b.toString()); 

me ocurrió la idea de que el código anterior de Get an OutputStream into a String.

4

Esto funcionó forma mí,

DecimalFormatSymbols SYMBOLS = DecimalFormatSymbols.getInstance(Locale.US); 

    if (value > 1 || value < -1) { 
     SYMBOLS.setExponentSeparator("e+"); 
    } else { 
     SYMBOLS.setExponentSeparator("e"); 
    } 

    DecimalFormat format = new DecimalFormat(sb.toString(), SYMBOLS); 
-1

Por qué no usar "0.0E + 0" patrón en su lugar? Tenga en cuenta el signo más antes del último cero.

+0

Debido a que los resultados de patrones sugeridos en un java.lang.IllegalArgumentException' que contiene el texto ': _Malformed patrón exponencial "0.0E + 0" _ –

0

¿Cómo utilizar?
Véase el método formatTest.

if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) es útil para un gran número

/** 
* inspired by:<br> 
* https://stackoverflow.com/a/13065493/8356718 
* https://stackoverflow.com/a/18027214/8356718 
* https://stackoverflow.com/a/25794946/8356718 
*/ 
public static String format(String number, int scale) { 
    BigDecimal value = new BigDecimal(number); 
    DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US); 
    BigDecimal positive = new BigDecimal(1);// scale is zero 
    positive.setScale(0);// unnecessary 
    BigDecimal negative = new BigDecimal(-1);// scale is zero 
    negative.setScale(0);// unnecessary 
    if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) { 
     symbols.setExponentSeparator("e+"); 
    } else { 
     symbols.setExponentSeparator("e"); 
    } 
    DecimalFormat formatter = new DecimalFormat("0.0E0", symbols); 
    formatter.setRoundingMode(RoundingMode.HALF_UP); 
    formatter.setMinimumFractionDigits(scale); 
    return formatter.format(value); 
} 

/** 
* set the scale automatically 
*/ 
public static String format(String number) { 
    BigDecimal value = new BigDecimal(number); 
    return format(number, value.scale() > 0 ? value.precision() : value.scale()); 
} 

/* 
output: 
---------- 
0e0 
1.0e-2 
-1.0e-2 
1.234560e-5 
-1.234560e-5 
1e0 
-1e0 
3e+0 
-3e+0 
2e+2 
-2e+2 
---------- 
0.0000000000e0 
1.0000000000e-2 
-1.0000000000e-2 
1.2345600000e-5 
-1.2345600000e-5 
1.0000000000e0 
-1.0000000000e0 
3.0000000000e+0 
-3.0000000000e+0 
2.0000000000e+2 
-2.0000000000e+2 
---------- 
*/ 
public static void formatTest() { 
    System.out.println("----------"); 
    System.out.println(format("0")); 
    System.out.println(format("0.01")); 
    System.out.println(format("-0.01")); 
    System.out.println(format("0.000")); 
    System.out.println(format("-0.000")); 
    System.out.println(format("1")); 
    System.out.println(format("-1")); 
    System.out.println(format("3")); 
    System.out.println(format("-3")); 
    System.out.println(format("200")); 
    System.out.println(format("-200")); 
    System.out.println("----------"); 
    System.out.println(format("0", 10)); 
    System.out.println(format("0.01", 10)); 
    System.out.println(format("-0.01", 10)); 
    System.out.println(format("0.000", 10)); 
    System.out.println(format("-0.000", 10)); 
    System.out.println(format("1", 10)); 
    System.out.println(format("-1", 10)); 
    System.out.println(format("3", 10)); 
    System.out.println(format("-3", 10)); 
    System.out.println(format("200", 10)); 
    System.out.println(format("-200", 10)); 
    System.out.println("----------"); 
} 
+0

favor editar se publicar para incluir una explicación de cómo responde la pregunta. –

Cuestiones relacionadas