2009-07-31 14 views
5

Ich benutze Javas DecimalFormat Klasse, um Zahlen in wissenschaftlicher Notation auszudrucken. Es gibt jedoch ein Problem, das ich habe. Ich brauche die Strings unabhängig vom Wert von fester Länge, und das Zeichen mit der Zehnerpotenz gibt es ab. Derzeit ist es das, was mein Format wie folgt aussieht:Java DecimalFormat Wissenschaftliche Notation Frage

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

Das gibt mir die folgenden Kombinationen: 1.0E1, 1.0E1, -1.0E1 und -1.0E-1.

kann ich setPositivePrefix verwenden zu erhalten: + 1.0E1, + 1.0E1, -1.0E1 und -1.0E-1, oder was auch immer Ich mag, aber es wirkt sich nicht auf das Zeichen der Macht !

Gibt es eine Möglichkeit, dies zu tun, damit ich Strings fester Länge haben kann? Vielen Dank!

Edit: Ah, also gibt es keine Möglichkeit, es mit Javas bestehenden DecimalFormat API zu tun? Danke für die Vorschläge! Ich denke, ich muss möglicherweise DecimalFormat Unterklasse, weil ich durch die Schnittstelle, die bereits vorhanden ist begrenzt werden.

Antwort

2

Hier ist eine Möglichkeit. Hokey, vielleicht, aber es funktioniert ...

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

Alternativ können Sie Unterklasse DecimalFormat, aber ich finde es in der Regel sauberer nicht von konkreten Klassen, Unterklasse.

2

Könnten Sie verwenden printf() statt:

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

Ausgang:

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

Wenn Sie stattdessen auf eine String ausgeben müssen, können Sie die Informationen auf Formatted Printing for Java (sprintf) Lizenz verwendet werden, zu tun.

EDIT: Wow, das PrintfFormat() Ding ist riesig und scheint nicht notwendig zu sein:

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

ich die Idee für den obigen Code aus Get an OutputStream into a String bekam.

4

Diese Form mich gearbeitet,

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

Warum Muster nicht verwenden Sie stattdessen "0.0e + 0"? Beachten Sie das Pluszeichen vor der letzten Null.

+0

Da die vorgeschlagenen Muster resultiert in einem 'java.lang.IllegalArgumentException' mit dem Text nützlich: _Malformed exponentiellen Muster "0.0e + 0" _ –

0

Wie zu verwenden?
Siehe formatTest Methode.

if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) ist für sehr große Zahlen

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

Sie bitte bearbeiten Post, um eine Erklärung zu enthalten, wie sie die Frage beantwortet. –

Verwandte Themen