Frage

Ich bin mit Java DecimalFormat Klassenzahl in wissenschaftlicher Notation auszudrucken. Allerdings gibt es ein Problem, das ich habe. Ich brauche die Saiten fester Länge zu sein, unabhängig von dem Wert, und das Zeichen auf der Zehnerpotenz ist es weg zu werfen. Derzeit ist es das, was mein Format wie folgt aussieht:

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

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

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

Gibt es eine Möglichkeit, dies zu tun, so dass ich Zeichenfolge festgelegt haben kann? Dank!

Edit: Ah, so gibt es keine Möglichkeit, sie mit Hilfe von Java bestehend zu tun DecimalFormat API? Vielen Dank für die Anregungen! Ich glaube, ich habe zu können Unterklasse DecimalFormat , weil ich durch die Schnittstelle beschränkt bin, die bereits vorhanden ist.

War es hilfreich?

Lösung

Hier ist ein Weg. 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.

Andere Tipps

Das funktionierte mich bilden,

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

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

Ausgabe:

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

Wenn Sie die Ausgabe auf einen String stattdessen benötigen, können Sie die Informationen verwenden, zur Verfügung gestellt unter Formatierter Druck für Java (sprintf) , das 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 habe die Idee für den obigen Code von href="https://stackoverflow.com/questions/216894"> Get.

Wie man verwendet?
Siehe formatTest Methode.

if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) ist nützlich 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.0000123456"));
    System.out.println(format("-0.0000123456"));
    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.0000123456", 10));
    System.out.println(format("-0.0000123456", 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("----------");
}

Warum nicht "0.0e + 0" -Muster statt? Hinweis auf das Pluszeichen vor dem letzten Null.

scroll top