2009-07-31 5 views
5

J'utilise la classe DecimalFormat de Java pour imprimer des nombres dans la notation scientifique. Cependant, il y a un problème que j'ai. J'ai besoin que les cordes soient de longueur fixe quelle que soit la valeur, et le signe sur la puissance de dix le jette. À l'heure actuelle, c'est ce que mon forme ressemble à:Java DecimalFormat Scientific Notation Question

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

Cela me donne les combinaisons suivantes: 1.0E1, 1.0E1, -1.0E1, et -1.0E-1.

Je peux utiliser setPositivePrefix pour obtenir: + 1.0E1, + 1.0E1, -1.0E1 et -1.0E-1, ou tout ce que je l'aime, mais elle ne touche pas le signe de la puissance !

Y at-il un moyen de le faire afin que je puisse avoir des chaînes de longueur fixe? Merci!

Edit: Ah, il n'y a donc aucun moyen de le faire en utilisant DecimalFormat API de Java existant? Merci pour les suggestions! Je pense que je devrais sous-classer DecimalFormat parce que je suis limité par l'interface qui est déjà en place.

Répondre

2

Voici un moyen. Hokey, peut-être, mais il fonctionne ...

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)); 
    } 
} 

Sinon, vous pouvez sous-classe DecimalFormat, mais je trouve généralement plus propre de ne pas sous-classe des classes concrètes.

2

Pouvez-vous utiliser à la place printf():

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); 

Sortie:

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

Si vous avez besoin de sortie vers un lieu String, vous pouvez utiliser les informations fournies à Formatted Printing for Java (sprintf) pour le faire.

EDIT: Wow, cette chose PrintfFormat() est énorme et semble être inutile:

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

J'eu l'idée du code ci-dessus de Get an OutputStream into a String.

4

Cette forme me traitèrent,

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

Pourquoi ne pas utiliser modèle "0.0E + 0" à la place? Notez le signe plus avant le dernier zéro.

+0

Parce que les résultats de motifs proposés dans un 'java.lang.IllegalArgumentException' contenant le texte: _Malformed modèle exponentiel « 0.0E + 0 » _ –

0

Comment utiliser?
Voir la méthode formatTest.

if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) est utile pour un très grand nombre

/** 
* 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

S'il vous plaît modifier vous poster pour inclure une explication de la façon dont il répond à la question. –