Java的DecimalFormat的科学记数法问题(Java DecimalFormat Scie

2019-09-21 17:57发布

我使用Java的的DecimalFormat类打印出科学记数法表示。 然而,有一个问题,我有。 我需要的字符串是固定长度,无论价值,并在十功率的符号把它扔了。 目前,这是我的格式如下:

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

这给了我以下组合:1.0E1,1.0E1,-1.0E1和-1.0E-1。

我可以用setPositivePrefix获得:+ 1.0E1,+ 1.0E1,-1.0E1和-1.0E-1,或任何我喜欢的,但它不会影响电源的标志!

有没有办法做到这一点,这样我可以有固定长度的字符串? 谢谢!

编辑:啊,所以没有办法做到这一点使用Java的现有DecimalFormat的 API? 感谢您的建议! 我想我可能有子类DecimalFormat的 ,因为我被这个已经到位接口的限制。

Answer 1:

这里有一种方法。 做作,也许,但它的工作原理...

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的,但我觉得它一般清洁不从具体类的子类。



Answer 2:

这个工作我形成,

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


Answer 3:

你可以使用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进入一个字符串 。



Answer 4:

如何使用?
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("----------");
}


Answer 5:

为什么不使用“0.0E + 0”模式呢? 注意最后零之前的加号。



文章来源: Java DecimalFormat Scientific Notation Question