سؤال

أنا أستخدم جافا تنسيق عشري فئة لطباعة الأرقام في الترميز العلمي.ومع ذلك، هناك مشكلة واحدة لدي.أحتاج إلى أن تكون السلاسل ذات طول ثابت بغض النظر عن القيمة، والعلامة الموجودة على قوة العشرة تتخلص منها.حاليًا، هذا ما يبدو عليه التنسيق الخاص بي:

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

هذا يعطيني المجموعات التالية:1.0E1، 1.0E-1، -1.0E1، و -1.0E-1.

استطيع ان استخدم setPositivePrefix تحصل:+1.0E1، +1.0E-1، -1.0E1، و -1.0E-1، أو ما أحبه، لكنه لا يؤثر على إشارة القوة!

هل هناك أي طريقة للقيام بذلك حتى أتمكن من الحصول على سلاسل ذات طول ثابت؟شكرًا!

يحرر:آه، لذلك لا توجد طريقة للقيام بذلك باستخدام Java الموجودة تنسيق عشري واجهة برمجة التطبيقات؟شكرا على الاقتراحات!أعتقد أنني قد تضطر إلى فئة فرعية تنسيق عشري لأنني مقيد بالواجهة الموجودة بالفعل.

هل كانت مفيدة؟

المحلول

هنا طريقة واحدة.ربما هوكي، لكنه يعمل...

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

بدلا من ذلك يمكنك فئة فرعية DecimalFormat، لكنني أجد أنه من الأنظف عمومًا عدم فصل فئة فرعية من فئات محددة.

نصائح أخرى

هذا نجح معي،

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

هل يمكن أن تستخدم 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);

انتاج:

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

إذا كنت بحاجة إلى الإخراج إلى ملف String بدلاً من ذلك، يمكنك استخدام المعلومات المقدمة على الطباعة المنسقة لـ Java (sprintf) للقيام بذلك.

يحرر:واو، هذا PrintfFormat() الشيء ضخم ويبدو أنه غير ضروري:

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

حصلت على فكرة الكود أعلاه من احصل على OutputStream في سلسلة.

كيف تستعمل؟
يرى formatTest طريقة.

if (value.compareTo(positive) == 1 || value.compareTo(negative) == -1) مفيد لأعداد كبيرة جدًا

/**
 * 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("----------");
}

لماذا لا تستخدم النمط "0.0E+0" بدلاً من ذلك؟لاحظ علامة الزائد قبل الصفر الأخير.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top